package com.iwhalecloud.bss.kite.cucc.web.controller.scene;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.cart.client.api.cart.query.IQueryKiteShoppingCartService;
import com.iwhalecloud.bss.kite.client.api.scene.operate.IOperateSceneService;
import com.iwhalecloud.bss.kite.client.api.scene.query.IQuerySceneCommonService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.client.dto.flow.KitePageDefineDTO;
import com.iwhalecloud.bss.kite.client.dto.inst.InstAttrDTO;
import com.iwhalecloud.bss.kite.client.vo.scene.CommonAttrVO;
import com.iwhalecloud.bss.kite.client.vo.spec.ServiceOfferTypeVO;
import com.iwhalecloud.bss.kite.client.vo.spec.ServiceOfferVO;
import com.iwhalecloud.bss.kite.common.callclient.service.rule.IRuleTriggerService;
import com.iwhalecloud.bss.kite.common.constant.*;
import com.iwhalecloud.bss.kite.common.context.CommonContext;
import com.iwhalecloud.bss.kite.common.rule.check.ICheckService;
import com.iwhalecloud.bss.kite.common.unicode.UnicodeOperTypeKite;
import com.iwhalecloud.bss.kite.common.util.*;
import com.iwhalecloud.bss.kite.cucc.client.api.attr.ILocalQueryScenePersonInfoService;
import com.iwhalecloud.bss.kite.cucc.client.api.batch.IBatchOrderNodeService;
import com.iwhalecloud.bss.kite.cucc.client.api.cust.ICustCheckQueryService;
import com.iwhalecloud.bss.kite.cucc.client.api.customerOrderInformation.ISerialNumberService;
import com.iwhalecloud.bss.kite.cucc.client.api.flow.IFlowService;
import com.iwhalecloud.bss.kite.cucc.client.api.goods.IGoodsModifyService;
import com.iwhalecloud.bss.kite.cucc.client.api.goods.IGoodsService;
import com.iwhalecloud.bss.kite.cucc.client.api.order.IBusinessChangeService;
import com.iwhalecloud.bss.kite.cucc.client.api.order.ICommonSevice;
import com.iwhalecloud.bss.kite.cucc.client.api.rule.check.ICuccCheckService;
import com.iwhalecloud.bss.kite.cucc.client.api.scene.ICuccSceneService;
import com.iwhalecloud.bss.kite.cucc.client.api.shoppingcart.operate.ICuccOperateShoppingCartService;
import com.iwhalecloud.bss.kite.cucc.client.dto.cust.CuccContextCustDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.customerOrderInformation.QryGrpMemberDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.customerOrderInformation.QryGrpMemberListByGrpReq;
import com.iwhalecloud.bss.kite.cucc.client.dto.flow.ProcessFlowchartDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.flow.TrackInfoDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.flow.TrackInfoDTO.FlowInfo;
import com.iwhalecloud.bss.kite.cucc.client.dto.goods.modify.request.AbstractCreateGoodsModifySceneRequest;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.pos.KitePosGoodsDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.scene.PageNavigationReqDTO;
import com.iwhalecloud.bss.kite.cucc.client.enumerate.UserDetailTagName;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.*;
import com.iwhalecloud.bss.kite.cucc.common.constant.CuccServiceOfferConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalServiceOfferConsts;
import com.iwhalecloud.bss.kite.cucc.common.dto.CuccContextDTO;
import com.iwhalecloud.bss.kite.cucc.common.util.DateUtils;
import com.iwhalecloud.bss.kite.cucc.common.util.KiteAssert;
import com.iwhalecloud.bss.kite.cucc.common.util.StrTools;
import com.iwhalecloud.bss.kite.cucc.dataservice.cache.CuccOfferOriginalInfoCache;
import com.iwhalecloud.bss.kite.cucc.dataservice.cache.ExtOrderInfoCache;
import com.iwhalecloud.bss.kite.cucc.manager.scene.service.operate.LocalOperateOfferInstAcctRelService;
import com.iwhalecloud.bss.kite.cucc.service.context.CuccServiceContext;
import com.iwhalecloud.bss.kite.cucc.service.even.BeforeSceneCommitEvent;
import com.iwhalecloud.bss.kite.cucc.service.goods.GoodsHelper;
import com.iwhalecloud.bss.kite.cucc.service.inf.InfServiceBus;
import com.iwhalecloud.bss.kite.cucc.service.pos.handler.CuccPosServiceUtils;
import com.iwhalecloud.bss.kite.cucc.service.util.ProdCateUtil;
import com.iwhalecloud.bss.kite.cucc.spec.impl.transfer.GoodsInfoTransfer;
import com.iwhalecloud.bss.kite.cucc.web.context.CuccKiteWebContext;
import com.iwhalecloud.bss.kite.cucc.web.controller.reception.LocalCustReceptionController;
import com.iwhalecloud.bss.kite.cucc.web.service.ISceneService;
import com.iwhalecloud.bss.kite.cucc.web.service.accept.handler.attr.IPersonAttrDealService;
import com.iwhalecloud.bss.kite.cucc.web.service.accept.vo.InitSceneVO;
import com.iwhalecloud.bss.kite.cucc.web.service.bigdata.util.OppoToSceneUtils;
import com.iwhalecloud.bss.kite.cucc.web.service.goods.modify.GoodsModifyServiceEnum;
import com.iwhalecloud.bss.kite.cucc.web.service.goods.modify.GoodsModifyServiceFactory;
import com.iwhalecloud.bss.kite.cucc.web.service.scene.PageNavigationService;
import com.iwhalecloud.bss.kite.dataservice.cache.AttrValueCache;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.cache.DcSystemParamCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.dataservice.entity.AttrValue;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.dataservice.entity.KitePageDefine;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Offer;
import com.iwhalecloud.bss.kite.dataservice.util.GeneralSwitchUtils;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.inst.*;
import com.iwhalecloud.bss.kite.manager.transaction.KiteTransactional;
import com.iwhalecloud.bss.kite.manager.util.KiteTransactionUtils;
import com.iwhalecloud.bss.kite.service.context.ServiceContext;
import com.iwhalecloud.bss.kite.web.context.KiteWebContext;
import com.iwhalecloud.bss.kite.web.service.accept.attr.ICommonAttrDealService;
import com.iwhalecloud.bss.kite.web.service.accept.vo.PageNavigationVO;
import com.iwhalecloud.bss.kite.web.util.RuleParamUtils;
import com.ztesoft.bss.base.staticdata.ServiceOfferConst;
import com.ztesoft.bss.base.util.LocalAttrUtils;
import com.ztesoft.bss.common.bo.LoginInfo;
import com.ztesoft.bss.common.bo.UserInfo;
import com.ztesoft.bss.common.exception.BssException;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.SpringUtil;
import com.ztesoft.bss.rul.core.client.dto.common.RuleCommonParam;
import com.ztesoft.common.logger.api.ZLogger;
import com.ztesoft.common.logger.factory.ZLoggerFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * <Description> 场景初始化 <br>
 *
 * @author huang.caibiao<br>
 * @version 1.0<br>
 * @see com.iwhalecloud.bss.kite.web.controller.order <br>
 * @since R9.0<br>
 */
@RestController("cuccSceneInit")
@RequestMapping("/cuccSceneInit")
@Api(tags = {"/cuccSceneInit - 场景受理初始化"
})
public class SceneInitController {

    private static final ZLogger LOGGER = ZLoggerFactory.getLogger(SceneInitController.class, KeyConsts.LOG_MODULE);

    @Autowired
    private IOperateSceneService operateSceneService;

    @Autowired
    private IOperateSceneInstService operateSceneInstService;

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    private ICommonAttrDealService commonAttrDealService;

    @Autowired
    private IQuerySceneCommonService querySceneCommonService;

    @Autowired
    IRuleTriggerService ruleTriggerService;

    @Autowired
    private IPersonAttrDealService personAttrDealService;

    @Autowired
    private ILocalQueryScenePersonInfoService queryScenePersonInfoService;

    @Autowired
    private LocalOperateOfferInstAcctRelService operateOfferInstAcctRelService;

    @Autowired
    private ICommonSevice commonService;

    @Autowired
    private ISceneService sceneService;

    @Autowired
    private ICuccSceneService cuccSceneService;

    @Autowired
    private IBusinessChangeService businessChangeService;

    @Resource
    private ApplicationContext applicationContext;

    @Autowired
    private IFlowService flowService;

    @Autowired
    private ICuccOperateShoppingCartService operateShoppingCartService;

    @Autowired
    private ICheckService checkService;

    @Autowired
    private IGoodsService goodsService;

    @Autowired
    private ICuccCheckService cuccCheckService;

    @Autowired
    private InfServiceBus  infServiceBus;


    @Autowired
    private ICustCheckQueryService custCheckQueryService;

    @ApiOperation(value = "新装场景初始化", notes = "新装场景初始化，返回场景实例标识")
    @PostMapping("/offer")
    public DataResult<String> initOfferScene(@RequestBody CuccOfferInitVO offerVO) {

        offerVO.setCustId(KiteWebContext.getContext().getCustId());
        offerVO.setCustName(KiteWebContext.getContext().getCust().getCustName());
        ServiceContext.setCust(KiteWebContext.getContext().getCustId(), this.sceneService.transToCustDTO((CuccContextCustDTO) KiteWebContext.getContext().getCust()));

        String sceneInstId = this.cuccSceneService.createOrderOfferScene(offerVO).getResultObject();
        KiteWebContext.addAndUpdateSceneInstId(sceneInstId);

        // app甩单订购初始化，回显甩单信息
        if(KiteStringUtils.isEqual(offerVO.getInitType(), "orderRejection")) {
            cuccSceneService.initRejectionSceneAttrValues(sceneInstId, offerVO);
        }

        String sceneInstIdd = sceneInstId;
        String kiteContextId = KiteWebContext.getKiteContextId();
        String custId = KiteWebContext.getContext().getCustId();
        CuccContextCustDTO custDTO = (CuccContextCustDTO) KiteWebContext.getContext().getCust();
        LoginInfo loginInfo = ContextUtil.getLoginInfo();
        CompletableFuture.runAsync(() -> {
            KiteWebContext.setKiteContextId(kiteContextId);
            KiteTransactionUtils.beginTransaction();
            try {
                //把登录信息设置给新线程
                ContextUtil.setLoginInfo2LoginInfoThreadLocal(loginInfo);
                //设置父级商品信息
                this.cuccSceneService.initParentOfferInfo(sceneInstIdd, custId, offerVO.getOfferId());
                //性能优化，改为这里异步获取userId，不在转单的时候串行获取
                this.cuccSceneService.initUserIdFromUserCenter(sceneInstIdd, custDTO);
                //性能优化，改为这里异步获取产品下的属性组实例ID，不在转单的时候串行获取
                this.cuccSceneService.initAttrGroupInstIdFromUserCenter(sceneInstIdd, custId, custDTO);
            }
            catch(Exception e) {
                throw new RuntimeException(e.getCause());
            }
            finally {
                KiteTransactionUtils.commit();
                KiteTransactionUtils.remove();
            }
        });
        return ErrorConsts.SUCCESS.getResult(sceneInstIdd);
    }

    @KiteTransactional
    @ApiOperation(value = "初始化公共属性", notes = "初始化公共属性,这个方法在初次初始化调用，从购物车修改进来不要调用")
    @ApiImplicitParams({@ApiImplicitParam(name = "sceneInstId", value = "场景实例标识", required = true)
    })
    @GetMapping("/commonAttr")
    public DataResult<List<CommonAttrVO>> initCommonAttr(@RequestParam String sceneInstId) {
        commonAttrDealService.initAttr();
        List<InstAttrDTO> attrConfigs = querySceneCommonService
            .listCommonAttrs(KiteWebContext.getContext().getCurrentSceneInstId(),
                KiteWebContext.getContext().getCustId()).getResultObject();
        if (attrConfigs == null) {
            return ErrorConsts.SUCCESS.getResult(Collections.emptyList());
        }
        Collections.sort(attrConfigs);

        return ErrorConsts.SUCCESS.getResult(
            attrConfigs.stream().map(attrDTO -> KiteBeanUtils.transform(attrDTO, CommonAttrVO.class))
                .collect(Collectors.toList()));
    }

    @KiteTransactional
    @ApiOperation(value = "初始化四类人属性", notes = "初始化四类人属性,这个方法在初次初始化调用，从购物车修改进来不要调用")
    @ApiImplicitParams({@ApiImplicitParam(name = "sceneInstId", value = "场景实例标识", required = true)
    })
    @GetMapping("/personAttr")
    public DataResult<List<CommonAttrVO>> initPersonAttr(@RequestParam String sceneInstId) {
        personAttrDealService.initAttr(sceneInstId, KiteWebContext.getContext().getCustId(), Boolean.TRUE);
        List<InstAttrDTO> attrConfigs = queryScenePersonInfoService
            .listAllKiteConfigAttrs(KiteWebContext.getContext().getCurrentSceneInstId(),
                KiteWebContext.getContext().getCustId()).getResultObject();
        if (attrConfigs == null) {
            return ErrorConsts.SUCCESS.getResult(Collections.emptyList());
        }
        Collections.sort(attrConfigs);

        return ErrorConsts.SUCCESS.getResult(
            attrConfigs.stream().map(attrDTO -> KiteBeanUtils.transform(attrDTO, CommonAttrVO.class))
                .collect(Collectors.toList()));
    }

    @KiteTransactional
    @ApiOperation(value = "取消场景", notes = "取消场景")
    @ApiImplicitParams({@ApiImplicitParam(name = "sceneInstId", value = "场景实例标识", required = true)
    })
    @DeleteMapping
    public DataResult<Boolean> cancelScene(@RequestParam String sceneInstId) {
        return ErrorConsts.SUCCESS.getResult(Boolean.TRUE);
    }

    @KiteTransactional
    @ApiOperation(value = "提交场景", notes = "提交场景，返回订单标识")
    @ApiImplicitParams({@ApiImplicitParam(name = "sceneInstId", value = "场景实例标识", required = true)
    })
    @PostMapping
    public DataResult<String> commitScene(@RequestParam String sceneInstId) {

        this.cuccSceneService.getCartIdFromES();

        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
        if (Objects.isNull(sceneInst)) {
            ErrorConsts.SCENE_INST_NOT_EXISTS.throwOut();
        }
        String serviceOfferId = sceneInst.getServiceOfferId();

        if (!"1003".equals(serviceOfferId) && !"1004".equals(serviceOfferId) && !"1005".equals(serviceOfferId)) {
            // 用户停机/用户复机/用户预销户跳过校验
            List<KiteOfferInstAcct> kiteOfferInstAcctList = operateOfferInstAcctRelService
                .listOfferInstAcctRels(sceneInstId);
            Boolean isDefauleAcctRel = kiteOfferInstAcctList.stream()
                .anyMatch(kiteOfferInstAcct -> "1".equals(kiteOfferInstAcct.getIsDefault()));

            if (KiteListUtils.isNotEmpty(kiteOfferInstAcctList) && !isDefauleAcctRel) {
                return ErrorConsts.BUSI_COMMON_ERROR.getResult("-1", "必须每个商品都有默认付费账户！");
            }
        }

        String loadingTariffPlanFlag = querySceneInstService.getExtParameterValue(sceneInstId, "loadingTariffPlanFlag");
        if (KiteStringUtils.equals(loadingTariffPlanFlag, KeyConsts.IFTRUE_T)) {
            return ErrorConsts.BUSI_COMMON_ERROR.getResult("-1", "服务端仍在还原场景信息，请稍候...");
        }
        else if (KiteStringUtils.equals(loadingTariffPlanFlag, KeyConsts.IFTRUE_F)) {
            return ErrorConsts.BUSI_COMMON_ERROR.getResult("-1", "服务端异步处理场景信息失败，请重新进入页面...");
        }

        String custId = KiteWebContext.getContext().getCustId();
        String staffId = ContextUtil.getUserId().toString();

        BeforeSceneCommitEvent beforeSceneCommitEvent = new BeforeSceneCommitEvent(this, custId, staffId, sceneInstId,
            serviceOfferId);
        applicationContext.publishEvent(beforeSceneCommitEvent);

        if (!LocalKeyConsts.ASK_SOURCE_ORDER.equals(sceneInst.getAskSource())) {
            CompletableFuture.runAsync(FunctionWrapper.wrapLoginInfoAndTrans(
                (Runnable) () -> this.operateShoppingCartService
                    .toSettle(ContextUtil.getSimpleLoginInfo(), sceneInstId, null,
                        ContextUtil.getSimpleLoginInfo().getUserId().toString(), custId,
                        KeyConsts.SHOPPING_CART_GROUP_STATUS_SETTLE)));
        }

        return this.operateSceneService.commitScene(sceneInstId, KiteWebContext.getContext().getCustId());
    }

    @SuppressWarnings("deprecation")
    @KiteTransactional
    @ApiOperation(value = "核查转定", notes = "二次业务销售品初始化，返回场景实例标识")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "政企订单中心的订单ID", required = true),
        @ApiImplicitParam(name = "serviceOfferId", value = "服务提供", required = false)
    })
    @GetMapping("/secondary/transferOrder")
    public DataResult<InitSceneVO> initTransferOrderScene(@RequestParam String orderId, String serviceOfferId) {

        String cartId = this.cuccSceneService.getCartIdFromES().getResultObject();

        String sceneInstId = this.sceneService
            .createOfferSceneByOrderDetailInfo(orderId, ServiceOfferConsts.SERVICE_OFFER_ORDER, "", "",
                ContextUtil.getUserId().toString(), ContextUtil.getLandId(),
                ContextUtil.getLoginInfo().getUserInfo().getPostRegionId().toString(),
                UnicodeOperTypeKite.OPERTYPE_1013).getResultObject();

        KiteSceneInst kiteSceneInst = this.querySceneInstService
            .getSceneInst(sceneInstId, KiteWebContext.getContext().getCustId());
        //回执信息
        this.operateSceneInstService.putExtParameter(sceneInstId, "outOrderId", orderId);
        //转单需要原单信息
        this.operateSceneInstService.putExtParameter(sceneInstId, "sourceOrderId", orderId);
        this.operateSceneInstService.putExtParameter(sceneInstId, "mainOfferInstId", kiteSceneInst.getRootInstId());

        this.sceneService.setSceneInstId(sceneInstId, cartId, UnicodeOperTypeKite.OPERTYPE_1013);
        ExtOrderInfoCache.getInst().defaultDelete(sceneInstId);

        String offerId = querySceneInstService
            .getKiteInst(KiteWebContext.getContext().getCustId(), kiteSceneInst.getRootInstType(),
                kiteSceneInst.getRootInstId()).getSpecId();
        Offer offer = OfferCache.get(offerId);
        String cateId = offer.getCateId();
        PageNavigationVO pageNavigationVO = SpringUtil.getBean(SceneController.class)
            .getPageNavigation(LocalServiceOfferConsts.SERVICE_OFFER_TRANSFER_TO_ORDER, offer.getOfferType(), offerId,
                sceneInstId, null, null).getResultObject();
        if (pageNavigationVO == null) {
            ErrorConsts.BUSI_COMMON_ERROR.throwOut("未配置模板或页面流程,请联系管理员");
        }
        return ErrorConsts.SUCCESS.getResult(new InitSceneVO(offerId, sceneInstId, pageNavigationVO, cateId, KiteWebContext.getContext().getCustId()));
    }

    @SuppressWarnings("deprecation")
    @ApiOperation(value = "根据订单详情创建场景", notes = "根据订单详情创建场景（查看订单详情创建场景用）")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "政企订单中心的订单ID", required = true),
        @ApiImplicitParam(name = "serviceOfferId", value = "服务提供", required = true),
        @ApiImplicitParam(name = "businessType", value = "页面URL中的操作类型", required = true),
        @ApiImplicitParam(name = "businessType", value = "页面URL中的操作类型", required = true),
        @ApiImplicitParam(name = "preTaskCode", value = "流程标识", required = false)
    })
    @GetMapping("/initOfferSceneByOrderDetailInfo")
    public DataResult<InitSceneVO> initOfferSceneByOrderDetailInfo(@RequestParam String orderId,
        @RequestParam String serviceOfferId, @RequestParam String businessType,
        @RequestParam(required = false) String operType, @RequestParam(required = false) String preTaskCode) {
        String cartId = this.cuccSceneService.getCartIdFromES().getResultObject();

        LoginInfo loginInfo = ContextUtil.getLoginInfo();
        String staffId = ContextUtil.getUserId().toString();
        String lanId = ContextUtil.getLandId();
        String regionId = loginInfo.getUserInfo().getPostRegionId().toString();
        String provinceId = loginInfo.getUserInfo().getPostProvinceNbr();
        Map<String, Object> dataMap = this.cuccSceneService.getOfferSceneDataByOrderDetailInfo(orderId, serviceOfferId,
            KeyConsts.KITE_SCENE_INST_OPER_TYPE_1000, "", "", staffId, lanId, regionId).getResultObject();

        KitePosDTO kitePosDTO = (KitePosDTO) KiteMapUtils.getObject(dataMap, "kitePosDTO");
        this.sceneService.initContext(kitePosDTO.getCustomer());

        // 二级研发跳转省份应用页面，不需要进行场景初始化，只需要获取页面流即可
        DataResult<InitSceneVO> secInitSceneNavigation = getSecSceneNavigation(serviceOfferId, dataMap, operType);
        // 判断获取的页面流是否为二级研发，如果是，直接返回
        boolean flag = this.judgeSaleKiteDecDev(secInitSceneNavigation);
        if (flag) {
            return secInitSceneNavigation;
        }
        if (GeneralSwitchUtils.isSwitchOpened("INIT_WITH_MUTIL_THREAD")) {
            CuccServiceContext.setIsCallInfForInitAttr(Boolean.FALSE);

            Map<String, Object> loginExtParams = loginInfo.getUserInfo().getExtParams();
            // 特殊参数,用于创建场景后设置场景参数用,该方法结束前移除
            loginExtParams.put("upServiceOfferId", KiteMapUtils.getString(dataMap, "upServiceOfferId"));
            loginExtParams.put("nodeCode", KiteMapUtils.getString(dataMap, "nodeCode"));

            String sceneInstId = this.cuccSceneService
                .initModifyScene(serviceOfferId, KeyConsts.KITE_SCENE_INST_OPER_TYPE_1000,
                    LocalKeyConsts.ASK_SOURCE_ORDER, KiteWebContext.getContext().getCustId(),
                    KiteWebContext.getContext().getCust().getCustName(), staffId, lanId, regionId, kitePosDTO)
                .getResultObject();

            KiteWebContext.addAndUpdateSceneInstId(sceneInstId);
            Map<String, Object> orderInfo = (Map<String, Object>)KiteMapUtils.getObject(dataMap, "orderInfo");
            this.cuccSceneService.initDetailSceneAttrValues(sceneInstId, serviceOfferId,
                KeyConsts.KITE_SCENE_INST_OPER_TYPE_1000, cartId, KiteWebContext.getContext().getCustId(), staffId,
                orderId, businessType, orderInfo, kitePosDTO, preTaskCode);

            String kiteContextId = KiteWebContext.getKiteContextId();
            CompletableFuture.runAsync(() -> {
                KiteWebContext.setKiteContextId(kiteContextId);
                KiteTransactionUtils.beginTransaction();
                try {
                    this.cuccSceneService.initMoreSceneAttrValues(sceneInstId, KiteWebContext.getContext().getCustId(),
                        staffId, provinceId, kitePosDTO);
                } catch (Exception e) {
                    // just log
                    LOGGER.error(ErrorConsts.SYSTEM_ERROR.getErrorCode(), e, ErrorConsts.SYSTEM_ERROR.getMsg());
                } finally {
                    KiteTransactionUtils.commit();
                    ContextUtil.removeThreadLocal();
                }
            });
            // 场景初始化完成,移除特殊参数
            loginExtParams.remove("upServiceOfferId");
            loginExtParams.remove("nodeCode");

            return ErrorConsts.SUCCESS
                .getResult(this.createInitSceneVOWithOrderFlow(sceneInstId, serviceOfferId, orderId));
        } else {
            return this.sceneService.initOfferSceneByOrderDetailInfo(orderId, serviceOfferId, businessType, cartId, preTaskCode);
        }
    }

    /**
     * 生成页面流对象
     * @param sceneInstId
     * @param serviceOfferId
     * @param orderId
     * @return
     */
    private InitSceneVO createInitSceneVOWithOrderFlow(String sceneInstId, String serviceOfferId, String orderId) {
        KiteSceneInst kiteSceneInst = this.querySceneInstService
            .getSceneInst(sceneInstId, KiteWebContext.getContext().getCustId());

        String offerId = querySceneInstService
            .getKiteInst(KiteWebContext.getContext().getCustId(), InstType.MAIN_OFFER_INST,
                kiteSceneInst.getRootInstId()).getSpecId();
        Offer offer = OfferCache.get(offerId);
        String cateId = offer.getCateId();
        PageNavigationVO pageNavigationVO = SpringUtil.getBean(SceneController.class)
            .getPageNavigation(serviceOfferId, offer.getOfferType(), offerId, sceneInstId, null, null)
            .getResultObject();
        if (pageNavigationVO == null) {
            ErrorConsts.BUSI_COMMON_ERROR.throwOut("未配置模板或页面流程,请联系管理员");
        }
        List<KitePageDefine> pageDefineList = new ArrayList<KitePageDefine>();
        // 特殊流程发起  调用接口获取订单中心的重新配置页面流程  只针对双线业务
        if(KiteStringUtils.equalsAny(cateId, ProdCateUtil.getDoubleLineCateIdForArr())){
            this.OrderProcessFlowchart(orderId,pageNavigationVO);
        }
        if (GeneralSwitchUtils.isSwitchOpened(LocalKeyConsts.ORDER_DETAIL_SWITCH)) {
            //查询订单详情的流程图
            ProcessFlowchartVO flowchartVO = flowService.getProcessFlowchart(orderId, "3");
            if (flowchartVO == null) {
                ErrorConsts.BUSI_COMMON_ERROR.throwOut("未查询到订单页面流程");
            }

            List<ProcessFlowchartDTO> flowchartList = flowchartVO.getFlowchartList();
            if (Objects.nonNull(flowchartList)) {
                for (ProcessFlowchartDTO processFlowchartDTO : flowchartList) {
                    KitePageDefine pageDefine = new KitePageDefine();
                    pageDefine.setStatusCd(LocalKeyConsts.COMMON_STATUS_VALIDATE);
                    pageDefine.setDefineId(String.valueOf(processFlowchartDTO.getSequ()));
                    pageDefine.setName(processFlowchartDTO.getName());
                    pageDefineList.add(pageDefine);
                }
                pageNavigationVO.setPageDefineList(pageDefineList);
            }
        }

        //查询订单当前环节
        if (StrTools.isEqual("1000", serviceOfferId)) {
            TrackInfoVO trackInfoVO = flowService.getOrderProgressInfo(orderId);
            if (Objects.nonNull(trackInfoVO)) {
                TrackInfoDTO trackList = trackInfoVO.getTrackList();
                Map<String, List<FlowInfo>> flowMap = trackList.getFlowInfoList();
                Entry<String, List<FlowInfo>> FlowInfo = flowMap.entrySet().iterator().next();
                String flowName = FlowInfo.getKey();
                pageDefineList = pageNavigationVO.getPageDefineList();
                for (KitePageDefine kitePageDefine : pageDefineList) {
                    if (StrTools.isEqual(kitePageDefine.getName(), flowName)) {
                        kitePageDefine.setPageUrl("/orderDeatils");
                    }
                }
            }
        }
        return new InitSceneVO(offerId, sceneInstId, pageNavigationVO, cateId, KiteWebContext.getContext().getCustId());
    }

    @ApiOperation(value = "根据工单信息创建场景", notes = "根据工单信息创建场景（订单待办点处理创建场景用）")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单id", required = true),
        @ApiImplicitParam(name = "flowId", value = "工单id", required = true),
        @ApiImplicitParam(name = "taskId", value = "任务单id", required = false),
        @ApiImplicitParam(name = "serviceOfferId", value = "服务提供", required = true),
        @ApiImplicitParam(name = "operType", value = "操作类型", required = true),
        @ApiImplicitParam(name = "orderSource", value = "订单来源", required = true),
        @ApiImplicitParam(name = "preTaskCode", value = "流程标识", required = false),
        @ApiImplicitParam(name = "toOrderType", value = "代办类型", required = false)
    })
    @GetMapping("/secondary/sign")
    public DataResult<InitSceneVO> initOfferSceneByWorkOrder(String orderId, String flowId, String taskId,
        String serviceOfferId, String operType, String orderSource,
        @RequestParam(value = "preTaskCode", required = false, defaultValue = "") String preTaskCode,
        @RequestParam(value = "toOrderType", required = false) String toOrderType) {
        LoginInfo loginInfo = ContextUtil.getLoginInfo();
        String staffId = ContextUtil.getUserId().toString();
        String lanId = ContextUtil.getLandId();
        String regionId = loginInfo.getUserInfo().getPostRegionId().toString();
        String postProvinceNbr = loginInfo.getUserInfo().getPostProvinceNbr();
        List<DcPublic> dcList = DcPublicCache.getByPcode("2021050801", "SALE_KITE_SECDEV", postProvinceNbr);

        // 获取工单信息
        Map<String, Object> dataMap;
        if(KiteStringUtils.isEqual(toOrderType, "chargePreCancel")) {
            // 收费方产品-代办发起的预销户操作
            dataMap = this.cuccSceneService.getOfferSceneDataForChargePreCancel(orderId, flowId, taskId, serviceOfferId, orderSource).getResultObject();
        } else {
            dataMap = this.cuccSceneService.getOfferSceneDataByWorkOrder(orderId, flowId, taskId, serviceOfferId,
                operType, "", "", staffId, lanId, regionId, orderSource).getResultObject();
        }

        // 如果有批量标识，根据子单查主单，用主单初始化场景
        Map<String, Object> orderInfo = SpringUtil.getBean(IBatchOrderNodeService.class).getOrderInfo(orderId,
            flowId, preTaskCode, serviceOfferId, staffId, lanId, regionId, dataMap);

        KitePosDTO kitePosDTO = (KitePosDTO) KiteMapUtils.getObject(dataMap, "kitePosDTO");
        this.sceneService.initContext(kitePosDTO.getCustomer());

        // 二级研发跳转省份应用页面，不需要进行场景初始化，只需要获取页面流即可
        DataResult<InitSceneVO> secInitSceneNavigation = getSecInitSceneNavigation(serviceOfferId, dataMap);

        // 判断获取的页面流是否为二级研发，如果是，直接返回
        boolean flag = this.judgeSaleKiteDecDev(secInitSceneNavigation);

        if (flag) {
            return secInitSceneNavigation;
        }


        String cartId = this.cuccSceneService.getCartIdFromES().getResultObject();
        Map<String, Object> loginExtParams = loginInfo.getUserInfo().getExtParams();
        loginExtParams.put("preTaskCode",  preTaskCode);
        if (GeneralSwitchUtils.isSwitchOpened("INIT_WITH_MUTIL_THREAD")) {
            CuccServiceContext.setIsCallInfForInitAttr(Boolean.FALSE);

            // 特殊参数,用于创建场景后设置场景参数用,该方法结束前移除
            String nodeCode = KiteMapUtils.getString(dataMap, "nodeCode");
            loginExtParams.put("nodeCode", nodeCode);
            loginExtParams.put("serviceOfferId", KiteMapUtils.getString(dataMap, "serviceOfferId"));
            loginExtParams.put("goodsNodeId", KiteMapUtils.getString(dataMap, "goodsNodeId"));

            String newServiceOfferId = KiteMapUtils.getString(dataMap, "serviceOfferId");
            // 获取客户ID和客户名称
            String custId = KiteWebContext.getContext().getCustId();
            String custName = KiteWebContext.getContext().getCust().getCustName();
            // 获取其它业务参数
            String upServiceOfferId = KiteMapUtils.getString(dataMap, "upServiceOfferId");
            List<String> serviceOfferIdList = (List<String>) KiteMapUtils.getObject(dataMap, "serviceOfferIdList");
            Map<String, Object> worksheetData = (Map<String, Object>) KiteMapUtils.getObject(dataMap, "worksheetData");
            JSONObject orderData = (JSONObject) KiteMapUtils.getObject(dataMap, "orderData");
            //加入订单失败原因
            if(KiteStringUtils.isNotEmpty(KiteMapUtils.getString(worksheetData, "orderData"))){
                JSONObject orderDataObj = JSONObject.parseObject(KiteMapUtils.getString(worksheetData, "orderData"));
                if(orderDataObj.containsKey("exceptionInfo")){
                    JSONObject expJson = orderDataObj.getJSONObject("exceptionInfo");
                    if(Objects.nonNull(expJson)&&expJson.containsKey("failReason")){
                        loginExtParams.put("BackReason",JSONObject.toJavaObject(expJson,Map.class));
                    }
                }
            }
            loginExtParams.put("orderSource", KiteMapUtils.getString(worksheetData, "orderSource"));

            // 创建场景
            String sceneInstId = this.cuccSceneService.createOfferScene(newServiceOfferId, operType, LocalKeyConsts.ASK_SOURCE_ORDER,
                custId, custName, staffId, lanId, regionId, kitePosDTO).getResultObject();
            // 批量受理子单查询详情时，不需要设置上下文
            if (!KiteStringUtils.equals(preTaskCode, "BatchSubOrderDetail")) {
                KiteWebContext.addAndUpdateSceneInstId(sceneInstId);
            }
            if(KiteStringUtils.isNotEmpty(toOrderType)) {
                // 收费方预销户补录，调订单归集接口，order节点需要传参数关闭代办，与落地方补录相同，共用落地方补录参数
                operateSceneInstService.putExtParameter(sceneInstId, "toOrderType", toOrderType);
                operateSceneInstService.putExtParameter(sceneInstId, "renderOrderType", "orderFallPlace");
                operateSceneInstService.putExtParameter(sceneInstId, "fallPlaceOrderId", orderId);
                operateSceneInstService.putExtParameter(sceneInstId, "fallPlaceFlowId", flowId);
            }
            if(KiteStringUtils.isNotEmpty(kitePosDTO.getOrder().getInitiatorOrderId())) {
                // 落地方/收费方重提，发起方订单id
                operateSceneInstService.putExtParameter(sceneInstId, "fallPlaceOrderId", kitePosDTO.getOrder().getInitiatorOrderId());
            }
            // 还原属性值
            this.cuccSceneService.initModifySceneAttrValues(sceneInstId, operType, custId, staffId, orderId, newServiceOfferId,
                upServiceOfferId, serviceOfferIdList, worksheetData, kitePosDTO, orderData);
            // 质检环节标记是否业务变更场景
            if (!KiteStringUtils.equalsAny(operType, "1", "1001")) {
                operateSceneInstService.putExtParameter(sceneInstId, LocalKeyConsts.BUSI_CHANGE_SCENE, "T");
            }
            // 质检过户设置custId
            KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
            if (KiteStringUtils.equals(sceneInst.getServiceOfferId(), ServiceOfferConsts.SERVICE_OFFER_TRANSFER)) {
                // 工单信息返回的custId已经是过户后的custId
                sceneInst.setNewCustId(custId);
                operateSceneInstService.setSceneInst(sceneInst);
            }
            if (KiteMapUtils.isNotEmpty(orderInfo)) {
                operateSceneInstService.putExtParameter(sceneInstId, "batchOrderInfo", orderInfo);
            }
            if (KiteStringUtils.equalsAny(preTaskCode, "batchSIGN", "batchOrderStartRent")) {
                String batchNodeCode = querySceneInstService.getExtParameterValue(sceneInstId, "nodeCode");
                operateSceneInstService.putExtParameter(sceneInstId, "nodeCode", "Batch" + batchNodeCode);
                String batchTaskCode = querySceneInstService.getExtParameterValue(sceneInstId, "taskCode");
                operateSceneInstService.putExtParameter(sceneInstId, "taskCode", "Batch" + batchTaskCode);
            }

            String kiteContextId = KiteWebContext.getKiteContextId();
            CompletableFuture.runAsync(() -> {
                KiteWebContext.setKiteContextId(kiteContextId);
                KiteTransactionUtils.beginTransaction();
                try {
                    this.cuccSceneService.initMoreSceneAttrValues(sceneInstId, custId, staffId, postProvinceNbr, kitePosDTO);
                }
                catch (Exception e) {
                    // just log
                    LOGGER.error(ErrorConsts.SYSTEM_ERROR.getErrorCode(), e, ErrorConsts.SYSTEM_ERROR.getMsg());
                }
                finally {
                    KiteTransactionUtils.commit();
                    ContextUtil.removeThreadLocal();
                }
            });

            InitSceneVO sceneVO = this.createInitSceneVO(sceneInstId, serviceOfferId, cartId, orderId,custId);
            // 场景初始化完成,移除特殊参数
            loginExtParams.remove("nodeCode");
            loginExtParams.remove("serviceOfferId");
            loginExtParams.remove("orderSource");
//            loginExtParams.remove("goodsNodeId");
            return ErrorConsts.SUCCESS.getResult(sceneVO);
        }
        else {
            return this.sceneService.initOfferSceneByWorkOrder(orderId, flowId, taskId, serviceOfferId, operType,
                orderSource, cartId, orderInfo, toOrderType, dataMap);
        }
    }

    private boolean judgeSaleKiteDecDev(DataResult<InitSceneVO> secInitSceneNavigation) {

        if (Objects.nonNull(secInitSceneNavigation) && Objects.nonNull(secInitSceneNavigation.getResultObject())) {
            InitSceneVO initSceneVO = secInitSceneNavigation.getResultObject();
            PageNavigationVO pageNavigationVO = initSceneVO.getPageNavigationVO();
            if (Objects.nonNull(pageNavigationVO) && KiteListUtils.isNotEmpty(pageNavigationVO.getPageDefineList())) {
                List<KitePageDefineDTO> pageDefineList = KiteBeanUtils.copyPropsForList(pageNavigationVO.getPageDefineList(), KitePageDefineDTO.class);

                if (KiteListUtils.isNotEmpty(pageDefineList)) {
                    List<KitePageDefineDTO> kitePageDefines = pageDefineList.stream()
                        .filter(pageDefine -> KiteStringUtils.equalsAny(pageDefine.getPageUrl(), "/kiteSecDev", "/kiteSecDevOrder"))
                        .collect(Collectors.toList());
                    if (KiteListUtils.isNotEmpty(kitePageDefines)) {
                        return true;
                    }

                }

            }

        }
        return false;
    }

    private DataResult<InitSceneVO> getSecInitSceneNavigation(String serviceOfferId, Map dataMap) {
//         LoginInfo loginInfo = ContextUtil.getLoginInfo();
        // 获取工单信息
//        Map<String, Object> dataMap = this.cuccSceneService.getOfferSceneDataByWorkOrder(orderId, flowId, taskId, serviceOfferId,
//            operType, "", "", ContextUtil.getUserId().toString(), ContextUtil.getLandId(),
//            loginInfo.getUserInfo().getPostRegionId().toString(), orderSource).getResultObject();

        String tacheCode = KiteMapUtils.getString(dataMap, "nodeCode");
        String newServiceOfferId = KiteMapUtils.getString(dataMap, "serviceOfferId");
        KitePosDTO kitePosDTO = (KitePosDTO) KiteMapUtils.getObject(dataMap, "kitePosDTO");

        String objId = null;
        String cateId = null;
        if (KiteStringUtils.isEqual(CuccServiceOfferConsts.SERVICE_OFFER_ADD_ORDER, newServiceOfferId)) {
            serviceOfferId = ServiceOfferConst.service_offer_1;
        }

        List<KitePosGoodsDTO> offerInsts = kitePosDTO.getGoods();

        for (KitePosGoodsDTO offerInst : offerInsts) {
            String offerId = offerInst.getCode();
            if (GoodsHelper.isGift(offerId)) {
                objId = offerId;
                cateId = offerInst.getCatagoryId();
                break;
            }
            if (GoodsHelper.isGroupGood(offerInst.getCatagoryId(),offerId)) {
                objId = offerId;
                cateId = offerInst.getCatagoryId();
                break;
            }
            if (!GoodsInfoTransfer.isAddRoleOffer(offerId, offerInst.getCatagoryId())) {
                objId = offerId;
                cateId = offerInst.getCatagoryId();
            }
        }

        PageNavigationReqDTO reqDTO = new PageNavigationReqDTO();

        reqDTO.setServiceOfferId(newServiceOfferId);
        reqDTO.setTacheCode(tacheCode);
        reqDTO.setObjId(objId);
        reqDTO.setCateId(cateId);

        DataResult<PageNavigationVO> pageNavigationVO = SpringUtil.getBean(PageNavigationService.class)
            .getPageNavigationVO(reqDTO);

//        if (pageNavigationVO.getResultObject() == null) {
//            ErrorConsts.BUSI_COMMON_ERROR.throwOut("未配置页面流程");
//        }
        Map result = new HashMap();
        String finalCateId = cateId;
        String province = Optional.ofNullable(ContextUtil.getLoginInfo().getUserInfo()).map(UserInfo::getPostProvinceNbr).orElse(null);
        List<DcPublic> dcPublicList = DcPublicCache.get("202012282032");
        // 将配置了 province 的排在前面
        dcPublicList.sort((t1, t2) -> {
            if(KiteStringUtils.isEmpty(t1.getCodee()) && KiteStringUtils.isNotEmpty(t2.getCodee())) {
                return 1;
            }
            return -1;
        });
        DcPublic dcPublic = dcPublicList.stream()
            .filter(cfg -> KiteStringUtils.equalsAny(cfg.getCodea(), finalCateId, "-1"))
            .filter(cfg -> newServiceOfferId.equals(cfg.getCodeb()))
            .filter(cfg -> KiteStringUtils.isEmpty(cfg.getCodee()) || KiteStringUtils.isEqual(province, cfg.getCodee()))
            .findFirst().orElse(null);

        if (!Objects.isNull(dcPublic)) { // 根据不同cateId和serviceOfferId，返回标识给前端，隐藏退单、重提按钮
            result.put("isChargeback", dcPublic.getCodec());
            result.put("isAgain", dcPublic.getCoded());
        }
        // app资源核查甩单补录，没有退单按钮，重提按钮名称改为提交
        if(KiteStringUtils.isEqual(tacheCode, "OrderAddRecord") && KiteStringUtils.isEqual(newServiceOfferId, "1012")) {
            result.put("isChargeback", "T");
            result.put("isAgain", "F");
        }

        PageNavigationVO resultObject = Objects.nonNull(pageNavigationVO) ? pageNavigationVO.getResultObject() : null;

        InitSceneVO initSceneVO = new InitSceneVO(objId, "", resultObject, result, cateId, "");

        return ErrorConsts.SUCCESS.getResult(initSceneVO);
    }


    /**
     * 生成页面流对象
     * @param sceneInstId
     * @param serviceOfferId
     * @param cartId
     * @return
     */
    private InitSceneVO createInitSceneVO(String sceneInstId, String serviceOfferId, String cartId,String orderId, String custId) {
        KiteSceneInst kiteSceneInst = this.querySceneInstService
            .getSceneInst(sceneInstId, KiteWebContext.getContext().getCustId());
        this.sceneService.setSceneInstId(sceneInstId, cartId, "");

        String offerId = querySceneInstService
            .getKiteInst(KiteWebContext.getContext().getCustId(), kiteSceneInst.getRootInstType(),
                kiteSceneInst.getRootInstId()).getSpecId();
        if (KiteStringUtils.isEmpty(serviceOfferId)) {
            serviceOfferId = kiteSceneInst.getServiceOfferId();
        }
        Offer offer = OfferCache.get(offerId);
        String cateId = offer.getCateId();
        String finalServiceOfferId = serviceOfferId;
        String province = Optional.ofNullable(ContextUtil.getLoginInfo().getUserInfo()).map(UserInfo::getPostProvinceNbr).orElse(null);

        List<DcPublic> dcPublicList = DcPublicCache.get("202012282032");
        // 将配置了 province 的排在前面
        dcPublicList.sort((t1, t2) -> {
            if(KiteStringUtils.isEmpty(t1.getCodee()) && KiteStringUtils.isNotEmpty(t2.getCodee())) {
                return 1;
            }
            return -1;
        });
        DcPublic dcPublic = dcPublicList.stream()
            .filter(cfg -> KiteStringUtils.equalsAny(cfg.getCodea(), cateId, "-1"))
            .filter(cfg -> finalServiceOfferId.equals(cfg.getCodeb()))
            .filter(cfg -> KiteStringUtils.isEmpty(cfg.getCodee()) || KiteStringUtils.isEqual(province, cfg.getCodee()))
            .findFirst().orElse(null);
        Map result = new HashMap();
        if (!Objects.isNull(dcPublic)) { // 根据不同cateId和serviceOfferId，返回标识给前端，隐藏退单、重提按钮
            result.put("isChargeback", dcPublic.getCodec());
            result.put("isAgain", dcPublic.getCoded());
        }
        // app资源核查甩单补录，没有退单按钮，重提按钮名称改为提交
        String renderOrderType = querySceneInstService.getExtParameterValue(sceneInstId, "renderOrderType");
        if(KiteStringUtils.isEqual(renderOrderType, "orderRejection")) {
            result.put("isChargeback", "T");
            result.put("isAgain", "F");
        }

        PageNavigationVO pageNavigationVO = SpringUtil.getBean(SceneController.class)
            .getPageNavigation(serviceOfferId, offer.getOfferType(), offerId, sceneInstId, null, null)
            .getResultObject();
        if (pageNavigationVO == null) {
            ErrorConsts.BUSI_COMMON_ERROR.throwOut("未配置模板或页面流程,请联系管理员");
        }
        // 调用接口获取订单中心的重新配置页面流程  只针对双线业务
        if(KiteStringUtils.equalsAny(cateId, ProdCateUtil.getDoubleLineCateIdForArr())){
            this.OrderProcessFlowchart(orderId,pageNavigationVO);
        }
        //添加意向客户标识给前端
        String isTransferOrderScene = querySceneInstService.getExtParameterValue(sceneInstId, "isTransferOrderScene");
        if(KiteStringUtils.equals(isTransferOrderScene,"T")&&custCheckQueryService.isYxCustType(custId)){
            result.put("userFlag","0");
        }else {
            result.put("userFlag","1");
        }
        //大数据产品将附加商品过滤
        OppoToSceneUtils.getInst().putOppoMembToContext(cateId,sceneInstId);
        return new InitSceneVO(offerId, sceneInstId, pageNavigationVO, result, cateId, KiteWebContext.getContext().getCustId());
    }

    @KiteTransactional
    @ApiOperation(value = "创建产品变更场景", notes = "创建产品变更场景，如停开机，预销户销户等")
    @ApiImplicitParams({@ApiImplicitParam(name = "serialNumber", value = "业务号码", required = true),
        @ApiImplicitParam(name = "serviceOfferId", value = "服务提供标识", required = true),
        @ApiImplicitParam(name = "prodId", value = "产品ID", required = false),
        @ApiImplicitParam(name = "userId", value = "用户实例ID", required = false)
    })
    @GetMapping("/secondary/initProdChangeScene")
    public DataResult<InitSceneVO> initProdChangeScene(@RequestParam String serialNumber,
                                                       @RequestParam String serviceOfferId, String prodId, String userId) {

        String cartId = this.cuccSceneService.getCartIdFromES().getResultObject();

        String sceneInstId = this.sceneService
            .createOfferScene(serialNumber, prodId, serviceOfferId, null, null, ContextUtil.getUserId().toString(),
                ContextUtil.getLandId(), ContextUtil.getLoginInfo().getUserInfo().getPostRegionId().toString(), userId)
            .getResultObject();

        KiteSceneInst kiteSceneInst = this.querySceneInstService
            .getSceneInst(sceneInstId, KiteWebContext.getContext().getCustId());
        //kiteSceneInst.setOperType(LocalKeyConsts.SCENE_OPER_TYPE_TRANSFER_PLAN_MODIFY); //传输计划变更
        //kiteSceneInst.setServiceOfferId(serviceOfferId);
        //this.operateSceneInstService.createSceneInst(kiteSceneInst);
        this.sceneService.setSceneInstId(sceneInstId, cartId, UnicodeOperTypeKite.OPERTYPE_1001);
        String offerId = querySceneInstService
            .getKiteInst(KiteWebContext.getContext().getCustId(), InstType.MAIN_OFFER_INST,
                kiteSceneInst.getRootInstId()).getSpecId();
        Offer offer = OfferCache.get(offerId);
        String cateId = offer.getCateId();
        String orderId = querySceneInstService.getExtParameterValue(sceneInstId, "orderId");
        PageNavigationVO pageNavigationVO = SpringUtil.getBean(SceneController.class)
            .getPageNavigation(serviceOfferId, offer.getOfferType(), offerId, sceneInstId, null, null)
            .getResultObject();
        if (pageNavigationVO == null) {
            ErrorConsts.BUSI_COMMON_ERROR.throwOut("未配置模板或页面流程,请联系管理员");
        }
        return ErrorConsts.SUCCESS.getResult(new InitSceneVO(offerId, sceneInstId, pageNavigationVO, cateId, KiteWebContext.getContext().getCustId()));

    }

    @KiteTransactional
    @ApiOperation(value = "二次业务产品类场景初始化", notes = "二次业务产品类场景初始化，返回场景实例标识")
    @ApiImplicitParams({@ApiImplicitParam(name = "accNum", value = "服务号码"),
        @ApiImplicitParam(name = "prodId", value = "产品ID", required = false),
        @ApiImplicitParam(name = "currentServiceOfferId", value = "当前操作类型", required = false),
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例ID", required = false),
        @ApiImplicitParam(name = "serviceOfferIds", value = "已勾选的操作类型", required = false),
        @ApiImplicitParam(name = "userId", value = "用户实例ID", required = false)
    })
    @GetMapping("/secondary/initBusinessChangeScene")
    public DataResult<InitSceneVO> initBusinessChangeScene(@RequestParam(required = false) String accNum,
                                                           @RequestParam String prodId, @RequestParam String currentServiceOfferId, @RequestParam String sceneInstId,
                                                           @RequestParam List<String> serviceOfferIds, @RequestParam String userId) {

        String cartId = this.cuccSceneService.getCartIdFromES().getResultObject();
        //校验操作类型互斥逻辑
        businessChangeService.checkSceneMutex(currentServiceOfferId, serviceOfferIds);
        if (KiteStringUtils.isNotEmpty(sceneInstId)) {
            KiteAssert.notBlank(accNum, ErrorConsts.ACCNUM_EMPTY);
        }
        return getInitSceneNavigation(cartId, accNum, prodId, currentServiceOfferId, serviceOfferIds, sceneInstId,
            KeyConsts.IFTRUE_F, userId);
    }

    private DataResult<InitSceneVO> getInitSceneNavigation(String cartId, String accNum, String prodId, String serviceOfferId,
                                                             List<String> serviceOfferIds, String sceneInstId, String flag, String userId) {
        boolean addOrderGenNum = false;
        if (KiteStringUtils.isEmpty(serviceOfferId)) {
            serviceOfferId = ServiceOfferConst.service_offer_2826;
        }
        else if (KiteStringUtils.isEqual(CuccServiceOfferConsts.SERVICE_OFFER_ADD_ORDER, serviceOfferId)) {
            addOrderGenNum = true;
        }
        if (KiteStringUtils.isNotEmpty(sceneInstId)) {
            operateSceneInstService.putExtParameter(sceneInstId, "BUSI_CHANGE_SERVICEOFFERID",
                serviceOfferIds); //将serviceOfferIdList放入场景中，便于在操作类型预览组件中获取
        } else {
            sceneInstId = this.sceneService
                .createOfferScene(accNum, prodId, serviceOfferId, "", "", ContextUtil.getUserId().toString(),
                    ContextUtil.getLandId(), ContextUtil.getLoginInfo().getUserInfo().getPostRegionId().toString(), userId)
                .getResultObject();
        }
        if (addOrderGenNum) { // 思路：追加订购（2019）变更业务要求新生成号码,这里加场景标识,确保第一次初始化公共属性的时候生成新号码,后续每次刷页面不生成新号码。
            serviceOfferId = ServiceOfferConst.service_offer_1;
            operateSceneInstService.putExtParameter(sceneInstId, LocalKeyConsts.ADD_ORDE_RGE_NNUM, "T");
            operateSceneInstService.putExtParameter(sceneInstId, LocalKeyConsts.ADD_ORDE, "T");
        }
        KiteSceneInst kiteSceneInst = this.querySceneInstService
            .getSceneInst(sceneInstId, KiteWebContext.getContext().getCustId());
        kiteSceneInst.setOperType(KeyConsts.KITE_SCENE_INST_OPER_TYPE_1000); //业务变更
        kiteSceneInst.setServiceOfferId(serviceOfferId);
        this.operateSceneInstService.createSceneInst(kiteSceneInst);
        this.sceneService.setSceneInstId(sceneInstId, cartId, "1008");
        if (!LocalKeyConsts.ASK_SOURCE_ORDER.equals(kiteSceneInst.getAskSource())) {
            this.sceneService.cacheShoppingCartGroup(sceneInstId, cartId);
        }
        String offerId = querySceneInstService
            .getKiteInst(KiteWebContext.getContext().getCustId(), InstType.MAIN_OFFER_INST,
                kiteSceneInst.getRootInstId()).getSpecId();
        Offer offer = OfferCache.get(offerId);
        String cateId = offer.getCateId();
        PageNavigationVO pageNavigationVO = SpringUtil.getBean(SceneController.class)
            .getPageNavigation(serviceOfferId, offer.getOfferType(), offerId, sceneInstId, null, null)
            .getResultObject();
        if (pageNavigationVO == null) {
            ErrorConsts.BUSI_COMMON_ERROR.throwOut("未配置模板或页面流程,请联系管理员");
        }
        operateSceneInstService.putExtParameter(sceneInstId, LocalKeyConsts.BUSI_CHANGE_SCENE, "T");

        return ErrorConsts.SUCCESS.getResult(new InitSceneVO(offerId, sceneInstId, pageNavigationVO, cateId, KiteWebContext.getContext().getCustId()));
    }

    @KiteTransactional
    @ApiOperation(value = "二次业务产品类场景初始化", notes = "二次业务产品类场景初始化，返回场景实例标识，不返回页面流信息")
    @ApiImplicitParams({@ApiImplicitParam(name = "accNum", value = "服务号码"),
        @ApiImplicitParam(name = "prodId", value = "产品ID", required = false),
        @ApiImplicitParam(name = "serviceOfferId", value = "当前操作类型", required = false),
        @ApiImplicitParam(name = "userId", value = "用户实例标识", required = false)
    })
    @GetMapping("/secondary/initBusinessChangeSceneOnly")
    public DataResult<InitSceneVO> initBusinessChangeSceneOnly(@RequestParam String accNum, @RequestParam String prodId, @RequestParam String serviceOfferId, @RequestParam String userId) {
        String custId = KiteWebContext.getContext().getCustId();
        String custName = KiteWebContext.getContext().getCust().getCustName();
        String staffId = ContextUtil.getUserId().toString();
        String staffCode = ContextUtil.getSimpleLoginInfo().getUserCode();
        String lanId = ContextUtil.getLandId();
        String provinceId = ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr();
        String regionId = ContextUtil.getLoginInfo().getUserInfo().getPostRegionId().toString();
        // 获取购物车ID
        String cartId = this.cuccSceneService.getCartIdFromES().getResultObject();
        //校验操作类型互斥逻辑
        List<String> serviceOfferIds = Lists.newArrayList();

        businessChangeService.checkSceneMutex(serviceOfferId, serviceOfferIds);
        if (false) {
            ServiceContext.setCust(custId, this.sceneService.transToCustDTO((CuccContextCustDTO) KiteWebContext.getContext().getCust()));
            CuccServiceContext.setIsCallInfForInitAttr(Boolean.FALSE);

            List<QryGrpMemberDTO> memberSerialNumbers = GeneralSwitchUtils.isSwitchOpened("QUERY_MEMBER_IN_SUBTHREAD")
                ? CuccKiteWebContext.getCuccContext().getMemberSerialNumbers()
                : null;

            Map<String, Object> resultMap = this.cuccSceneService
                .createOfferScene(accNum, memberSerialNumbers, prodId,
                    serviceOfferId, custId, custName, staffId, lanId, regionId, cartId, userId)
                .getResultObject();
            String sceneInstId = KiteMapUtils.getString(resultMap, "sceneInstId");
            KiteWebContext.addAndUpdateSceneInstId(sceneInstId);

            KitePosDTO kitePosDTO = (KitePosDTO) KiteMapUtils.getObject(resultMap, "kitePosDTO");
            this.cuccSceneService.initSceneAttrValues(sceneInstId, null, custId, staffId, kitePosDTO);

            String kiteContextId = KiteWebContext.getKiteContextId();
            CompletableFuture.runAsync(() -> {
                KiteWebContext.setKiteContextId(kiteContextId);
                KiteTransactionUtils.beginTransaction();
                try {
                    this.cuccSceneService.initMoreSceneAttrValues(sceneInstId, custId, staffCode, provinceId, kitePosDTO);
                }
                catch (Exception e) {
                    // just log
                    LOGGER.error(ErrorConsts.SYSTEM_ERROR.getErrorCode(), e, ErrorConsts.SYSTEM_ERROR.getMsg());
                }
                finally {
                    KiteTransactionUtils.commit();
                    ContextUtil.removeThreadLocal();
                }
            });

            operateSceneInstService.putExtParameter(sceneInstId, ExtParamConsts.EXT_PARAM_PROD_INST_IDS,
                querySceneInstService.listProdInsts(sceneInstId).stream().map(KiteProdInst::getProdInstId).collect(Collectors.toList()));
            return getInitSceneNavigation(sceneInstId, cartId, accNum, prodId, serviceOfferId, KeyConsts.IFTRUE_F);
        }
        else {
            DataResult<InitSceneVO> result = this.sceneService.getInitSceneVODataResult(cartId, accNum, prodId, serviceOfferId, userId, KeyConsts.IFTRUE_F);

            KiteSceneInst kiteSceneInst = this.querySceneInstService.getSceneInst(result.getResultObject().getSceneInstId());
            if (!LocalKeyConsts.ASK_SOURCE_ORDER.equals(kiteSceneInst.getAskSource())) {
                this.sceneService.cacheShoppingCartGroup(kiteSceneInst.getSceneInstId(), cartId);
            }
            return result;
        }
    }

    private DataResult<InitSceneVO> getInitSceneNavigation(String sceneInstId, String cartId, String accNum, String prodId,
        String serviceOfferId, String flag) {
        KiteSceneInst kiteSceneInst = this.querySceneInstService
            .getSceneInst(sceneInstId, KiteWebContext.getContext().getCustId());
        if (!LocalKeyConsts.ASK_SOURCE_ORDER.equals(kiteSceneInst.getAskSource())) {
            this.sceneService.cacheShoppingCartGroup(sceneInstId, cartId);
        }
        KiteInst inst =  querySceneInstService
            .getKiteInst(KiteWebContext.getContext().getCustId(), InstType.MAIN_OFFER_INST,
                kiteSceneInst.getRootInstId());
        if(KiteObjectUtils.isEmpty(inst)) {
            inst =  querySceneInstService
                .getKiteInst(KiteWebContext.getContext().getCustId(), InstType.GIFT_OFFER_INST,
                    kiteSceneInst.getRootInstId());
        }
        String offerId = inst.getSpecId();
        Offer offer = OfferCache.get(offerId);
        String cateId = offer.getCateId();
        OppoToSceneUtils.getInst().putOppoMembToContext(cateId,sceneInstId);
        return ErrorConsts.SUCCESS.getResult(new InitSceneVO(offerId, sceneInstId, null, cateId, KiteWebContext.getContext().getCustId()));
    }

    @KiteTransactional
    @ApiOperation(value = "业务变更取消业务场景还原", notes = "业务变更取消业务场景还原，返回场景实例标识")
    @ApiImplicitParams({@ApiImplicitParam(name = "accNum", value = "服务号码", required = false),
        @ApiImplicitParam(name = "prodId", value = "产品ID", required = false),
        @ApiImplicitParam(name = "currentServiceOfferId", value = "当前操作类型", required = false),
        @ApiImplicitParam(name = "sceneInstId", value = "场景实例ID", required = false),
        @ApiImplicitParam(name = "serviceOfferIds", value = "已勾选的操作类型", required = false)
    })
    @GetMapping("/secondary/cancleBusinessChangeScene")
    public DataResult<InitSceneVO> cancleBusinessChangeScene(@RequestParam(required = false) String accNum,
                                                             @RequestParam String prodId, @RequestParam String currentServiceOfferId, @RequestParam String sceneInstId,
                                                             @RequestParam List<String> serviceOfferIds) {

        String cartId = null;
        Map<String, Object> extParams = ContextUtil.getLoginInfo().getUserInfo().getExtParams();
        if (KiteMapUtils.isNotEmpty(extParams) && Objects.isNull(extParams.get("KITE_SCENEINST_CARTID"))) {

            Long staffId = ContextUtil.getUserId();

            // 获取购物车的分片键，调用ES进行查询，暂时先放在登录信息缓存中,方便场景加载的时候从购物车中获取数据需要通过分片键获取 ，后续改动
            IQueryKiteShoppingCartService queryKiteShoppingCartService = SpringUtil
                .getBean(IQueryKiteShoppingCartService.class);
            // 获取分片键 cartId
            Long cartIdl = queryKiteShoppingCartService.getShoppingCartIdByEs(staffId.toString()).getResultObject();

            if (!KiteObjectUtils.isEmpty(cartIdl)) {
                cartId = cartIdl.toString();
                extParams.put("KITE_SCENEINST_CARTID", cartIdl.toString());
            }
        }

        businessChangeService.restoreScene(currentServiceOfferId, sceneInstId, KiteWebContext.getContext().getCustId());
        if (KiteStringUtils.isNotEmpty(sceneInstId)) {
            KiteAssert.notBlank(accNum, ErrorConsts.ACCNUM_EMPTY);
        }
        return getInitSceneNavigation(cartId, accNum, prodId, currentServiceOfferId, serviceOfferIds, sceneInstId,
            KeyConsts.IFTRUE_T, "");
    }

    @KiteTransactional
    @ApiOperation(value = "二次类业务服务提供初始化", notes = "二次类业务服务提供初始化")
    @ApiImplicitParams({@ApiImplicitParam(name = "goodsId", value = "商品ID", required = false),
        @ApiImplicitParam(name = "cateId", value = "分类ID", required = false),
        @ApiImplicitParam(name = "cbssUserId", value = "cbss用户id", required = false),
        @ApiImplicitParam(name = "serialNumber", value = "业务号码", required = false),
        @ApiImplicitParam(name = "userState", value = "用户状态", required = false),
        @ApiImplicitParam(name = "userName", value = "用户名", required = false),
        @ApiImplicitParam(name = "custId", value = "客户标识", required = false),
        @ApiImplicitParam(name = "instanceType", value = "实例类型 10C:销售品 10A:产品", required = false),
        @ApiImplicitParam(name = "userId", value = "用户标识", required = false),
        @ApiImplicitParam(name = "modifyType", value = "变更来源标识：如果不为空并且等于[checkForModify],则来自核查变更", required = false)
    })
    @GetMapping("/secondary/serviceOfferChangeScene")
    public DataResult<List> serviceOfferChangeScene(@RequestParam(required = false) String goodsId,
                                                    @RequestParam(required = false) String cateId, @RequestParam(required = false) String cbssUserId,
                                                    @RequestParam(required = false) String serialNumber, @RequestParam(required = false) String userState,
                                                    @RequestParam(required = false) String userName, @RequestParam(required = false) String custId,
                                                    @RequestParam(required = false) String instanceType, @RequestParam(required = false) String userId,
                                                    @RequestParam(required = false) String modifyType) {
        // 页面多开，这里再初始化客户信息，解决选择客户后在选择用户页面搜索其他客户下的号码时的客户信息未更新问题
        SpringUtil.getBean(LocalCustReceptionController.class).initContext(custId, null);

        if (GeneralSwitchUtils.isSwitchOpened("QUERY_MEMBER_IN_SUBTHREAD")) {
            CompletableFuture<List<CuccServiceOfferTypeVO>> result = CompletableFuture.supplyAsync(FunctionWrapper
                .wrapLoginInfo((Supplier<?>) () -> {
                String contextId = KiteWebContext.getKiteContextId();
                List<QryGrpMemberDTO> memberSerialNumbers = this.cuccSceneService.queryMemberSerialNumbers(goodsId, serialNumber)
                    .getResultObject();
                CuccContextDTO context = new CuccContextDTO();
                context.setMemberSerialNumbers(memberSerialNumbers);
                CuccKiteWebContext.initCuccContext(contextId, context);
                return Lists.newArrayList();
            })).thenCombine(
                CompletableFuture.supplyAsync(FunctionWrapper
                    .wrapLoginInfo((Supplier<List<CuccServiceOfferTypeVO>>) () -> {
                        LocaleContextHolder.setLocale(Locale.CHINESE);
                        return this.getServiceOfferTypeVOList(goodsId,
                            cateId, cbssUserId, serialNumber, userState, userName, custId, instanceType, userId, modifyType);
                    })),
                (result1, result2) -> {
                    return result2;
                });
            return ErrorConsts.SUCCESS.getResult(result.join());
        }
        else {
            return ErrorConsts.SUCCESS.getResult(this.getServiceOfferTypeVOList(goodsId,
                cateId, cbssUserId, serialNumber, userState, userName, custId, instanceType, userId, modifyType));
        }
    }

    private List<CuccServiceOfferTypeVO> getServiceOfferTypeVOList(String goodsId, String cateId, String cbssUserId,
        String serialNumber, String userState, String userName, String custId, String instanceType, String userId,
        String modifyType) {
        if (KiteStringUtils.isEmpty(instanceType)) {
            instanceType = "10A";
        }
        /*点击用户规则埋点-start*/
        RuleCommonParam ruleCommonParam = RuleParamUtils.getRuleParam(custId);
        checkService.checkSelectCustData(custId, ruleCommonParam);
        /*点击用户规则埋点-end*/

        //查询商品信息,添加商品分类
        Map<String, Object> goodsInfoMap = CuccOfferOriginalInfoCache.get(goodsId);
        if (KiteMapUtils.isNotEmpty(goodsInfoMap)) {
            cateId = KiteMapUtils.getString(goodsInfoMap, "cateId");
        }

        List<ServiceOfferTypeVO> serviceOfferTypeList = businessChangeService.queryServiceOfferInfo(goodsId, cateId, custId, instanceType, modifyType);

        String allFlag = DcPublicCache.getCodea("2019061408", "rule_all_close_flag");
        if (KiteStringUtils.equals(allFlag, "T")) {

            /**二次类业务菜单置灰规则校验-start*/
            Map<String, String> userInfo = new HashMap<String, String>();
            userInfo.put("cbssUserId", cbssUserId);
            userInfo.put("serialNumber", serialNumber);
            userInfo.put("goodsId", goodsId);
            userInfo.put("userState", userState);
            userInfo.put("userName", userName);
            userInfo.put("cateId", cateId);
            userInfo.put("userId", userId);
            userInfo.put("custId", custId);
            List<CuccServiceOfferTypeVO> cuccOfferTypeList = this.onServiceOfferChangeSceneMenuCheck(serviceOfferTypeList, userInfo);
            /**二次类业务菜单置灰规则校验-end*/
            return cuccOfferTypeList;
        }
        List<CuccServiceOfferTypeVO> cuccServiceOfferTypeVOList = new ArrayList<>();
        for (ServiceOfferTypeVO serviceOfferTypeVO : serviceOfferTypeList) {
            CuccServiceOfferTypeVO cuccServiceOfferTypeVO = KiteBeanUtils.transform(serviceOfferTypeVO, CuccServiceOfferTypeVO.class);
            List<CuccServiceOfferVo> cuccServiceOfferVO = Lists.newArrayList();
            for (ServiceOfferVO serviceOffer : serviceOfferTypeVO.getServiceOfferViews()) {
                CuccServiceOfferVo cuccserviceOffer = KiteBeanUtils.transform(serviceOffer, CuccServiceOfferVo.class);
                cuccserviceOffer.setCateId(KiteMapUtils.getString(goodsInfoMap, "cateId"));
                cuccServiceOfferVO.add(cuccserviceOffer);
            }
            cuccServiceOfferTypeVO.setServiceOfferViews(cuccServiceOfferVO);
            cuccServiceOfferTypeVOList.add(cuccServiceOfferTypeVO);
        }
        return cuccServiceOfferTypeVOList;
    }

    @KiteTransactional
    @ApiOperation(value = "打印免填单模板", notes = "打印免填单模板")
    @ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单id", required = true),
        @ApiImplicitParam(name = "flowId", value = "工单id", required = true),
        @ApiImplicitParam(name = "taskId", value = "任务单id", required = false),
        @ApiImplicitParam(name = "serviceOfferId", value = "服务提供", required = true),
        @ApiImplicitParam(name = "operType", value = "操作类型", required = true)
    })
    @GetMapping("/printTemplateScene")
    public DataResult<Map<String, Object>> printTemplateScene(String orderId, String flowId, String taskId,
                                                              String serviceOfferId, String operType) {
        String sceneInstId = this.sceneService
            .createOfferSceneByWorkOrder(orderId, flowId, taskId, serviceOfferId, operType, "", "",
                ContextUtil.getUserId().toString(), ContextUtil.getLandId(),
                ContextUtil.getLoginInfo().getUserInfo().getPostRegionId().toString()).getResultObject();

        Map<String, Object> result = this.sceneService.dealPrintTemplate(sceneInstId, serviceOfferId);
        return ErrorConsts.SUCCESS.getResult(result);
    }

    @KiteTransactional
    @ApiOperation(value = "打印免填单模板（订单录入）", notes = "打印免填单模板（订单录入）")
    @ApiImplicitParams({@ApiImplicitParam(name = "sceneInstId", value = "场景实例id", required = true),
        @ApiImplicitParam(name = "serviceOfferId", value = "服务提供", required = true)
    })
    @GetMapping("/printTemplateSceneForInput")
    public DataResult<Map<String, Object>> printTemplateScene(String sceneInstId, String serviceOfferId) {
        Map<String, Object> result = this.sceneService.dealPrintTemplate(sceneInstId, serviceOfferId);
        return ErrorConsts.SUCCESS.getResult(result);
    }

    /**
     * 二次类业务菜单置灰规则校验
     *
     * @return
     */
    public List<CuccServiceOfferTypeVO> onServiceOfferChangeSceneMenuCheck(List<ServiceOfferTypeVO> serviceOfferTypeVOList, Map<String, String> userInfo) {
        String userState = KiteMapUtils.getString(userInfo, "userState");
        String cateId = KiteMapUtils.getString(userInfo, "cateId");
        Map<String,Object> requestParam = new HashMap<String,Object>();
        Map<String,Object> userDetailInfo = new HashMap<String,Object>();

        List<CuccServiceOfferTypeVO> cuccServiceOfferTypeVOList = new ArrayList<>();
        if (KiteListUtils.isEmpty(serviceOfferTypeVOList)) {
            return cuccServiceOfferTypeVOList;
        }

        //服务提供dcPublic配置
        List<DcPublic> dcPublics = DcPublicCache.get("20201216004");
        Map<String, String> serviceOfferMap = new HashMap<String, String>();
        dcPublics.forEach(dcPublic -> {
            serviceOfferMap.put(dcPublic.getPkey(), dcPublic.getCodea());
        });


        //用户状态dcPublic配置
        List<DcPublic> userStateDcPublics = DcPublicCache.get("20200201001");
        Map<String,String> userStateMap = new HashMap<String,String>();
        userStateDcPublics.forEach(dcPublic -> {
            userStateMap.put(dcPublic.getPkey(), dcPublic.getCodea());
        });

        //获取用户状态信息
        String stateName = "";
        AttrValue attrValue = AttrValueCache.getAttrValue("2020122201", userState);
        if (Objects.nonNull(attrValue)) {
            stateName = attrValue.getAttrValueName();
        }


        /**不校验在途单的服务提供id*/
        String exceptServiceOfferId = DcPublicCache.getCodea("2021031801", "exspectServiceOfferId");

        //在途单校验new
        boolean PassageOrderSwitch = GeneralSwitchUtils.isSwitchOpened("KitePassageOrder");
        boolean passageOrderFlag = true;
        if (PassageOrderSwitch) {
            Map checkReqMap = new HashMap();
            checkReqMap.put("SERIAL_NUMBER", KiteMapUtils.getString(userInfo, "serialNumber"));
            checkReqMap.put("TYPE", "order");
            checkReqMap.put("GOODS_CATAGORY_ID", cateId);
            ISerialNumberService bean = SpringUtil.getBean(ISerialNumberService.class);
            Map checkMap = bean.checkPassageOrder(checkReqMap);
            if (!KiteStringUtils.isEqual(KiteMapUtils.getString(checkMap, "code"), "00000")) {
                BssException.throwOut("", "", "校验业务号码是否有在途单接口失败：" + KiteMapUtils.getString(checkMap, "message"));
            }
            passageOrderFlag = KiteMapUtils.getBooleanValue(checkMap, "data", true);
        }
        // 销户需要用到，提前
        requestParam.put("userInfo", userInfo);

        //如果为销户，预销户状态则不能受理任何业务-start
        if (KiteStringUtils.equalsAny(userState, LocalKeyConsts.LOCAL_USER_STATE_XH, LocalKeyConsts.LOCAL_USER_STATE_YXH)) {

            for (ServiceOfferTypeVO serviceOfferTypeVO : serviceOfferTypeVOList) {
                CuccServiceOfferTypeVO cuccServiceOfferTypeVO = KiteBeanUtils.transform(serviceOfferTypeVO, CuccServiceOfferTypeVO.class);

                List<ServiceOfferVO> serviceOfferVOList = serviceOfferTypeVO.getServiceOfferViews();
                List<CuccServiceOfferVo> cuccServiceOfferVoList = new ArrayList<>();
                for (ServiceOfferVO serviceOfferVO : serviceOfferVOList) {
                    CuccServiceOfferVo cuccServiceOfferVo = KiteBeanUtils.transform(serviceOfferVO, CuccServiceOfferVo.class);
                    cuccServiceOfferVo.setCateId(cateId);
                    cuccServiceOfferVo.setIsEdit("0");
                    cuccServiceOfferVo.setRemark("当前用户为【" + stateName + "】状态，不允许办理当前业务");
                    if (KiteStringUtils.equals(userState, LocalKeyConsts.LOCAL_USER_STATE_YXH) && LocalServiceOfferConsts.SERVICE_OFFER_XIAOHU.equals(serviceOfferVO.getServiceOfferId())) {
                        // 预销户状态可以做销户
                        cuccServiceOfferVo.setIsEdit("1");
                        cuccServiceOfferVo.setRemark(null);
                        // 判断是否存在在途单
                        List<String> otherServiceOfferId = new ArrayList<>();
                        otherServiceOfferId.add(serviceOfferVO.getServiceOfferId());
                        if (PassageOrderSwitch) {
                            if (passageOrderFlag) {
                                cuccServiceOfferVo.setIsEdit("0");
                                cuccServiceOfferVo.setRemark("用户存在在途单，不允许受理业务，请将在途单处理报竣");
                            }
                        }
                        else {
                            Map<String, Object> cancelCheckResultMap = cuccCheckService.onInitServiceOfferChangeScene(requestParam, otherServiceOfferId);
                            Map<String, String> cancelMenuCheckResult = (Map<String, String>) cancelCheckResultMap.get(serviceOfferVO.getServiceOfferId());
                            //在途单
                            if (KiteStringUtils.equals(KeyConsts2.USER_STATE_HAS_ORDER, KiteMapUtils.getString(cancelMenuCheckResult, "hasOrder"))
                                && !KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())) {
                                cuccServiceOfferVo.setIsEdit("0");
                                cuccServiceOfferVo.setRemark(KiteMapUtils.getString(cancelMenuCheckResult, "hasOrderMsg"));
                            }
                        }
                    }
                    cuccServiceOfferVoList.add(cuccServiceOfferVo);
                }
                cuccServiceOfferTypeVO.setServiceOfferViews(cuccServiceOfferVoList);
                cuccServiceOfferTypeVOList.add(cuccServiceOfferTypeVO);
            }
            return cuccServiceOfferTypeVOList;
        }
        //如果为销户，预销户状态则不能受理任何业务-end

        //获取OA账号信息  云业务才需要校验
        Map<String,Object> oaAccountMap = new HashMap<>();
        if (KiteStringUtils.equalsAny(cateId, "2000998", "2100982")) {
            oaAccountMap = infServiceBus.queryOaAccount();
        }
        requestParam.put("oaAccountInfo", oaAccountMap);


        Map<String,Object> inParam = new HashMap<>();
        inParam.put("provinceCode", ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr());
        inParam.put("eparchyCode", ContextUtil.getLoginInfo().getUserInfo().getPostLanId());
        inParam.put("staffCode", ContextUtil.getLoginInfo().getStaffInfo().getStaffCode());
        inParam.put("accNum",userInfo.get("serialNumber"));
        Map<String,Object> userDetailMap = infServiceBus.queryUserDetail(inParam, Lists.newArrayList(
            UserDetailTagName.USER,
            UserDetailTagName.PAYRELATION,
            UserDetailTagName.USER_ITEM,
            UserDetailTagName.USER_SERVICE,
            UserDetailTagName.USER_SERVICE_ITEM,
            UserDetailTagName.USER_DISCNT,
            UserDetailTagName.USER_DISCNT_ITEM));

        // SDWAN是否弹性升速截止时间内，是则不允许预销户、停机
        boolean sdwanElasticFlag = false;
        // SDWAN：平台下单的用户，不能在销售中心进行业务变更
        if(KiteStringUtils.equals(cateId, "2101120")) {
            boolean isSdwanPlatUser = false;
            List<Map> userServiceInfos = (List)userDetailMap.get("USER_SERVICE_INFOS");
            if(KiteListUtils.isNotEmpty(userServiceInfos)){
                String isFromSdwanPlat = null;
                String elasticStartDate = null;
                String elasticEndDate = null;
                for(Map userServiceInfo: userServiceInfos){
                    List<Map<String,Object>> userServiceItemInfos = (List)userServiceInfo.get("USER_SERVICE_ITEM_INFOS");
                    if(KiteListUtils.isEmpty(userServiceItemInfos)){
                        continue;
                    }
                    Map<String,Object> isFromSdwanPlatAttr = userServiceItemInfos.stream().filter(userServiceitemInfo ->
                        KiteStringUtils.equals("200004482", KiteMapUtils.getString(userServiceitemInfo, "CRM_ATTR_CODE"))).findFirst().orElse(null);
                    isFromSdwanPlat = KiteMapUtils.getString(isFromSdwanPlatAttr, "CRM_ATTR_VALUE");
                    // 弹性升速开始日期
                    Map<String,Object> elasticStartAttr = userServiceItemInfos.stream().filter(userServiceitemInfo ->
                        KiteStringUtils.equals("200002715", KiteMapUtils.getString(userServiceitemInfo, "CRM_ATTR_CODE"))).findFirst().orElse(null);
                    elasticStartDate = KiteMapUtils.getString(elasticStartAttr, "CRM_ATTR_VALUE");
                    // 弹性升速截止日期
                    Map<String,Object> elasticEndAttr = userServiceItemInfos.stream().filter(userServiceitemInfo ->
                        KiteStringUtils.equals("200002140", KiteMapUtils.getString(userServiceitemInfo, "CRM_ATTR_CODE"))).findFirst().orElse(null);
                    elasticEndDate = KiteMapUtils.getString(elasticEndAttr, "CRM_ATTR_VALUE");
                }
                isSdwanPlatUser = KiteStringUtils.equals(isFromSdwanPlat, "1_0000106");
                sdwanElasticFlag = DateUtils.compareDate(elasticStartDate, elasticEndDate);
            }
            // sdwan平台用户
            if(isSdwanPlatUser) {
                for (ServiceOfferTypeVO serviceOfferTypeVO : serviceOfferTypeVOList) {
                    CuccServiceOfferTypeVO cuccServiceOfferTypeVO = KiteBeanUtils.transform(serviceOfferTypeVO, CuccServiceOfferTypeVO.class);
                    List<ServiceOfferVO> serviceOfferVOList = serviceOfferTypeVO.getServiceOfferViews();
                    List<CuccServiceOfferVo> cuccServiceOfferVoList = new ArrayList<>();
                    for (ServiceOfferVO serviceOfferVO : serviceOfferVOList) {
                        CuccServiceOfferVo cuccServiceOfferVo = KiteBeanUtils.transform(serviceOfferVO, CuccServiceOfferVo.class);
                        cuccServiceOfferVo.setCateId(cateId);
                        cuccServiceOfferVo.setIsEdit("0");
                        cuccServiceOfferVo.setRemark("此订单为SDWAN平台自助下单，请到SDWAN平台进行变更");
                        cuccServiceOfferVoList.add(cuccServiceOfferVo);
                    }
                    cuccServiceOfferTypeVO.setServiceOfferViews(cuccServiceOfferVoList);
                    cuccServiceOfferTypeVOList.add(cuccServiceOfferTypeVO);
                }
                return cuccServiceOfferTypeVOList;
            }
        }

        // 获取用户属性-是否总部收费
        String isCharged = "";
        //获取A端省份，Z端省份
        String aProvinceNbr = "";
        String zProvinceNbr = "";
        if(KiteMapUtils.isNotEmpty(userDetailMap)){
            //获取是否总部收费
            List<Map<String,Object>> userItemInfos = (List)userDetailMap.get("USER_ITEM_INFOS");
            if(KiteListUtils.isNotEmpty(userItemInfos)){
                for(Map<String,Object> userItemInfo : userItemInfos){
                    if(KiteStringUtils.equalsAny(KiteMapUtils.getString(userItemInfo, "CRM_ATTR_CODE"),
                        LocalKeyConsts.IS_LEADER_CHARGE,LocalKeyConsts.IS_LEADER_CHARGE_NEW)){
                        if(KiteStringUtils.equalsAny(KiteMapUtils.getString(userItemInfo, "ATTR_VALUE"),"1","1_0000106")){
                            isCharged = "1_0000106";
                        }
                        if(KiteStringUtils.equalsAny(KiteMapUtils.getString(userItemInfo, "ATTR_VALUE"),"0","1_0000107")){
                            isCharged = "1_0000107";
                        }
                        break;
                    }
                }
            }

            //获取AZ端省份
            List<Map> userServiceInfos = (List)userDetailMap.get("USER_SERVICE_INFOS");
            if(KiteListUtils.isNotEmpty(userServiceInfos)){
                for(Map userServiceInfo: userServiceInfos){
                    List<Map<String,Object>> userServiceItemInfos = (List)userServiceInfo.get("USER_SERVICE_ITEM_INFOS");
                    if(KiteListUtils.isEmpty(userServiceItemInfos)){
                        continue;
                    }
                    Map<String,Object> aProvinceAttr = userServiceItemInfos.stream().filter(userServiceitemInfo ->
                        KiteStringUtils.equals("2_0000220", KiteMapUtils.getString(userServiceitemInfo, "CRM_ATTR_CODE"))).findFirst().orElse(null);
                    aProvinceNbr = KiteMapUtils.getString(aProvinceAttr, "CRM_ATTR_VALUE");
                    Map<String,Object> zProvinceAttr = userServiceItemInfos.stream().filter(userServiceitemInfo ->
                        KiteStringUtils.equals("2_0000107", KiteMapUtils.getString(userServiceitemInfo, "CRM_ATTR_CODE"))).findFirst().orElse(null);
                    zProvinceNbr = KiteMapUtils.getString(zProvinceAttr, "CRM_ATTR_VALUE");
                }
            }
            // 付费关系
            userDetailInfo.put("PAYRELATION_INFOS", userDetailMap.get("PAYRELATION_INFOS"));
            // 资费信息
            userDetailInfo.put("USER_DISCNT_INFOS", userDetailMap.get("USER_DISCNT_INFOS"));
            // 产品信息
            userDetailInfo.put("USER_SERVICE_INFOS", userDetailMap.get("USER_SERVICE_INFOS"));
        }
        requestParam.put("userDetailInfo", userDetailInfo);
        requestParam.put("cateId", cateId);

        if(KiteStringUtils.isNotEmpty(isCharged)){
            userInfo.put("isCharged", isCharged);
        }
        userInfo.put("aDomain", aProvinceNbr);
        userInfo.put("zDomain", zProvinceNbr);

        List<String> serviceOfferIdList = new ArrayList<>();
        for (ServiceOfferTypeVO serviceOfferTypeVO : serviceOfferTypeVOList) {
            List<ServiceOfferVO> serviceOfferVOList = serviceOfferTypeVO.getServiceOfferViews();
            for (ServiceOfferVO serviceOfferVO : serviceOfferVOList) {
                serviceOfferIdList.add(serviceOfferVO.getServiceOfferId());
            }
        }
        Map<String, Object> checkResultMap = cuccCheckService.onInitServiceOfferChangeScene(requestParam, serviceOfferIdList);

        // 5G切片需要判断集团下无成员，才可以进行预销户
        boolean fiveSectionFlag = false;
        String cataIdstr = DcPublicCache.getPCode("20210802094701", "5GSection");
        if(KiteStringUtils.equalsAny(cateId, cataIdstr.split(SymbolConsts.COMMA))) {
            String userId = KiteMapUtils.getString(userInfo, "userId");
            QryGrpMemberListByGrpReq qryGrpMemberListByGrpReq = new QryGrpMemberListByGrpReq();
            qryGrpMemberListByGrpReq.setPrimaryUserId(userId);
            qryGrpMemberListByGrpReq.setQueryOldSystem("2");
            qryGrpMemberListByGrpReq.setCurPage(1);
            qryGrpMemberListByGrpReq.setPageSize(1);
            Map<String,Object> GrpMemberListMap = infServiceBus.qryGrpMemberListByGrpNew(qryGrpMemberListByGrpReq);
            if (KiteMapUtils.isNotEmpty(GrpMemberListMap)) {
                //成员用户数量
                Integer rowCount = KiteMapUtils.getInteger(GrpMemberListMap, "ROW_COUNT");
                if (rowCount != null && rowCount>0) {
                    fiveSectionFlag = true;
                }
            }
        }

        for (ServiceOfferTypeVO serviceOfferTypeVO : serviceOfferTypeVOList) {
            CuccServiceOfferTypeVO cuccServiceOfferTypeVO = KiteBeanUtils.transform(serviceOfferTypeVO, CuccServiceOfferTypeVO.class);
            List<ServiceOfferVO> serviceOfferVOList = serviceOfferTypeVO.getServiceOfferViews();
            List<CuccServiceOfferVo> cuccServiceOfferVoList = new LinkedList<>();
            for (ServiceOfferVO serviceOfferVO : serviceOfferVOList) {
                CuccServiceOfferVo cuccServiceOfferVo = KiteBeanUtils.transform(serviceOfferVO, CuccServiceOfferVo.class);
                cuccServiceOfferVo.setCateId(cateId);
                Map<String,String>  menuCheckResult = (Map<String,String>)checkResultMap.get(serviceOfferVO.getServiceOfferId());

                // 需求九：停开机菜单合并规则只作用于五大专线
                if (KiteStringUtils.equalsAny(cateId, ProdCateUtil.getDoubleLineCateIdForArr())
                    //IDC目前与双线规则一致
                    || KiteStringUtils.equalsAny(cateId, ProdCateUtil.getIDCCateIdForArr())) {
                    //用户申请停机-停机状态校验(用户为申请停机状态，仅允许操作【开机】)
                    if (KiteStringUtils.equals(userState, KiteMapUtils.getString(userStateMap, "sqtj"))
                        && !KiteStringUtils.equalsAny(cuccServiceOfferVo.getServiceOfferId(), serviceOfferMap.get("kj"), serviceOfferMap.get("yhyxh"))
                        && !KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())) {
                        cuccServiceOfferVo.setIsEdit("0");
                        cuccServiceOfferVo.setRemark("当前用户为【" + stateName + "】状态，不允许办理当前业务");
                    }

                    //状态强制停机，只能做开机
                    if (KiteStringUtils.equals(userState, KiteMapUtils.getString(userStateMap, "qztj"))
                        && !KiteStringUtils.equalsAny(cuccServiceOfferVo.getServiceOfferId(), serviceOfferMap.get("kj"), serviceOfferMap.get("yhyxh"))
                        && !KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())) {
                        cuccServiceOfferVo.setIsEdit("0");
                        cuccServiceOfferVo.setRemark("当前用户为【" + stateName + "】状态，不允许办理当前业务");
                    }

                    // 开机
                    if(KiteStringUtils.equals(serviceOfferMap.get("kj"), serviceOfferVO.getServiceOfferId())) {
                        if (KiteStringUtils.equalsAny(userState, LocalKeyConsts.LOCAL_USER_STATE_KT)) {
                            // 如果为开通，不允许受理开机业务
                            cuccServiceOfferVo.setCateId(cateId);
                            cuccServiceOfferVo.setIsEdit("0");
                            cuccServiceOfferVo.setRemark("当前用户为【" + stateName + "】状态，不允许办理开机业务");
                        } else if(LocalAttrUtils.isCrossDomainForUserDetail(cateId, userDetailMap)) {
                            // 以太网、SDH、互联网，跨域，不支持停开机
                            cuccServiceOfferVo.setCateId(cateId);
                            cuccServiceOfferVo.setIsEdit("0");
                            cuccServiceOfferVo.setRemark("跨域业务不能进行开机");
                        }
                    }

                    // 停机
                    if(KiteStringUtils.equals(serviceOfferMap.get("tj"), serviceOfferVO.getServiceOfferId())) {
                        // 如果为申请停机、欠费停机、特殊停机，不允许受理停机业务
                        if (KiteStringUtils.equalsAny(userState, LocalKeyConsts.LOCAL_USER_STATE_SQTJ, LocalKeyConsts.LOCAL_USER_STATE_QFTJ, LocalKeyConsts.LOCAL_USER_STATE_TSTJ)) {
                            cuccServiceOfferVo.setCateId(cateId);
                            cuccServiceOfferVo.setIsEdit("0");
                            cuccServiceOfferVo.setRemark("当前用户为【" + stateName + "】状态，不允许办理停机业务");
                        } else if(LocalAttrUtils.isCrossDomainForUserDetail(cateId, userDetailMap)) {
                            // 以太网、SDH、互联网，跨域，不支持停开机
                            cuccServiceOfferVo.setCateId(cateId);
                            cuccServiceOfferVo.setIsEdit("0");
                            cuccServiceOfferVo.setRemark("跨域业务不能进行停机");
                        }
                    }

                    // 双线销户规则，用户为预销户状态下放开销户菜单，其他状态销户菜单不给放开
                    if (!KiteStringUtils.equals(userState, LocalKeyConsts.LOCAL_USER_STATE_YXH) && !KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())
                        && KiteStringUtils.equals(serviceOfferMap.get("yhxh"), serviceOfferVO.getServiceOfferId())) {
                        cuccServiceOfferVo.setCateId(cateId);
                        cuccServiceOfferVo.setIsEdit("0");
                        cuccServiceOfferVo.setRemark("当前用户为【" + stateName + "】状态，不允许办理销户业务");
                    }
                }
                else {
                    //用户申请停机-停机状态校验(用户为申请停机状态，仅允许操作【用户申请开机】、【特殊开机】【开机】)
                    if (KiteStringUtils.equals(userState, KiteMapUtils.getString(userStateMap, "sqtj"))
                        && !KiteStringUtils.equalsAny(cuccServiceOfferVo.getServiceOfferId(), serviceOfferMap.get("yhsqkj"), serviceOfferMap.get("qzkj"), serviceOfferMap.get("kj"))
                        && !KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())) {
                        cuccServiceOfferVo.setIsEdit("0");
                        cuccServiceOfferVo.setRemark("当前用户为【" + stateName + "】状态，不允许办理当前业务");
                    }

                    //状态是开通，置灰申请开机,强制开机，开机菜单
                    if (KiteStringUtils.equalsAny(userState, KiteMapUtils.getString(userStateMap, "kt"))
                        && KiteStringUtils.equalsAny(cuccServiceOfferVo.getServiceOfferId(),
                        KiteMapUtils.getString(serviceOfferMap, "yhsqkj"),
                        KiteMapUtils.getString(serviceOfferMap, "qzkj"), serviceOfferMap.get("kj")) && !KiteStringUtils
                        .equals("0", cuccServiceOfferVo.getIsEdit())) {
                        cuccServiceOfferVo.setIsEdit("0");
                        cuccServiceOfferVo.setRemark("当前用户为【" + stateName + "】状态，不允许办理当前业务");
                    }

                    //状态强制停机，只能做强制开机，开机
                    if (KiteStringUtils.equals(userState, KiteMapUtils.getString(userStateMap, "qztj"))
                        && !KiteStringUtils.equalsAny(cuccServiceOfferVo.getServiceOfferId(), KiteMapUtils.getString(serviceOfferMap, "qzkj"), KiteMapUtils.getString(serviceOfferMap, "kj"))
                        && !KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())) {
                        cuccServiceOfferVo.setIsEdit("0");
                        cuccServiceOfferVo.setRemark("当前用户为【" + stateName + "】状态，不允许办理当前业务");
                    }
                }

                //cbss用户校验
                if (KiteStringUtils.equals(KeyConsts2.IS_CBSS_USER_EMPTY_T, KiteMapUtils.getString(menuCheckResult, "isCbssUserEmpty"))
                    &&!"0".equals(cuccServiceOfferVo.getIsEdit())) {
                    cuccServiceOfferVo.setIsEdit("0");
                    cuccServiceOfferVo.setRemark(KiteMapUtils.getString(menuCheckResult, "isCbssUserEmptyMsg"));
                }

                if (KiteStringUtils.equals(serviceOfferMap.get("ffgx"), serviceOfferVO.getServiceOfferId())) {
                    //在途单
                    if (PassageOrderSwitch) {
                        if (passageOrderFlag) {
                            cuccServiceOfferVo.setIsEdit("0");
                            cuccServiceOfferVo.setRemark("用户存在在途单，不允许受理业务，请将在途单处理报竣");
                        }
                    }
                    else {
                        if (KiteStringUtils.equals(KeyConsts2.USER_STATE_HAS_ORDER, KiteMapUtils.getString(menuCheckResult, "hasOrder"))) {
                            cuccServiceOfferVo.setIsEdit("0");
                            cuccServiceOfferVo.setRemark(KiteMapUtils.getString(menuCheckResult, "hasOrderMsg"));
                        }
                    }
                } else if (KiteStringUtils.equals(serviceOfferMap.get("yhyxh"), serviceOfferVO.getServiceOfferId())) {
                    //在途单
                    if (PassageOrderSwitch) {
                        if (passageOrderFlag) {
                            cuccServiceOfferVo.setIsEdit("0");
                            cuccServiceOfferVo.setRemark("用户存在在途单，不允许受理业务，请将在途单处理报竣");
                        }
                    }
                    else {
                        if (KiteStringUtils.equals(KeyConsts2.USER_STATE_HAS_ORDER, KiteMapUtils.getString(menuCheckResult, "hasOrder"))
                            && !KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())) {
                            cuccServiceOfferVo.setIsEdit("0");
                            cuccServiceOfferVo.setRemark(KiteMapUtils.getString(menuCheckResult, "hasOrderMsg"));
                        }
                    }

                    //资费生效时间是否到期
                    if (KiteStringUtils.equals(KeyConsts2.IS_EFF_DATE_VALID_F,
                        KiteMapUtils.getString(menuCheckResult, "isEffDateValid"))
                      && !KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())){
                        cuccServiceOfferVo.setIsEdit("0");
                        cuccServiceOfferVo.setRemark(KiteMapUtils.getString(menuCheckResult, "isEffDateValidMsg"));
                    }

                    //欠费校验
                    if (KiteStringUtils.equals(KeyConsts2.IS_OUT_OF_CREDIT_T, KiteMapUtils.getString(menuCheckResult, "isOutOfCredit"))
                      && !KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())) {
                        cuccServiceOfferVo.setIsEdit("0");
                        cuccServiceOfferVo.setRemark(KiteMapUtils.getString(menuCheckResult, "isOutOfCreditMsg"));
                    }

                    // SDWAN
                    if (sdwanElasticFlag) {
                        cuccServiceOfferVo.setIsEdit("0");
                        cuccServiceOfferVo.setRemark("弹性升速生效中，不允许预销户，请先取消弹性升速");
                    }
                    //5G切片需要集团下无成员，才可以进行预销户
                    if (fiveSectionFlag) {
                        cuccServiceOfferVo.setIsEdit("0");
                        cuccServiceOfferVo.setRemark("集团下无成员，才可以进行预销户");
                    }
                } else if (KiteStringUtils.equals(serviceOfferMap.get("cpbg"), serviceOfferVO.getServiceOfferId())) {
                    //在途单
                    if (PassageOrderSwitch) {
                        if (passageOrderFlag) {
                            cuccServiceOfferVo.setIsEdit("0");
                            cuccServiceOfferVo.setRemark("用户存在在途单，不允许受理业务，请将在途单处理报竣");
                        }
                    }
                    else {
                        if (KiteStringUtils.equals(KeyConsts2.USER_STATE_HAS_ORDER, KiteMapUtils.getString(menuCheckResult, "hasOrder"))
                            && !KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())) {
                            cuccServiceOfferVo.setIsEdit("0");
                            cuccServiceOfferVo.setRemark(KiteMapUtils.getString(menuCheckResult, "hasOrderMsg"));
                        }
                    }
                    //欠费校验
                    if (KiteStringUtils.equals(KeyConsts2.IS_OUT_OF_CREDIT_T, KiteMapUtils.getString(menuCheckResult, "isOutOfCredit"))
                      && !KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())) {
                        cuccServiceOfferVo.setIsEdit("0");
                        cuccServiceOfferVo.setRemark(KiteMapUtils.getString(menuCheckResult, "isOutOfCreditMsg"));
                    }
                } else {
                    // COP产品下的成员加入、成员退出不校验在途单
                    String copCataIdstr = DcPublicCache.getPCode("20210922103801", "CopCataIdstr");
                    if(!KiteStringUtils.equalsAny(cateId, copCataIdstr.split(SymbolConsts.COMMA))) {
                        //在途单
                        if (PassageOrderSwitch) {
                            if (passageOrderFlag) {
                                cuccServiceOfferVo.setIsEdit("0");
                                cuccServiceOfferVo.setRemark("用户存在在途单，不允许受理业务，请将在途单处理报竣");
                            }
                        }
                        else {
                            if (KiteStringUtils.equals(KeyConsts2.USER_STATE_HAS_ORDER, KiteMapUtils.getString(menuCheckResult, "hasOrder"))
                                && !KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())
                                && !KiteStringUtils.commaContains(exceptServiceOfferId, serviceOfferVO.getServiceOfferId())) {
                                cuccServiceOfferVo.setIsEdit("0");
                                cuccServiceOfferVo.setRemark(KiteMapUtils.getString(menuCheckResult, "hasOrderMsg"));
                            }
                        }
                    }

                    // SDWAN + 用户申请停机
                    if (sdwanElasticFlag && KiteStringUtils.equals(serviceOfferMap.get("yhsqtj"), serviceOfferVO.getServiceOfferId())) {
                        cuccServiceOfferVo.setIsEdit("0");
                        cuccServiceOfferVo.setRemark("当前在弹性升速时间内，不允许进行停机");
                    }
                    //欠费校验
                    else if (KiteStringUtils.equals(KeyConsts2.IS_OUT_OF_CREDIT_T, KiteMapUtils.getString(menuCheckResult, "isOutOfCredit"))
                        //停机不校验欠费
                        && !KiteStringUtils.equalsAny(cuccServiceOfferVo.getServiceOfferId(),
                        KiteMapUtils.getString(serviceOfferMap, "yhsqtj"),KiteMapUtils.getString(serviceOfferMap, "tstj"))
                        && !KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())) {

                        //【用户申请开机，用户申请停机】，欠费提示拦截。
                        if(KiteStringUtils.equalsAny(cuccServiceOfferVo.getServiceOfferId(), KiteMapUtils.getString(serviceOfferMap, "yhsqkj"),
                            KiteMapUtils.getString(serviceOfferMap, "yhsqtj"))){
                            cuccServiceOfferVo.setIsEdit("3");
                            cuccServiceOfferVo.setRemark("欠费用户不允许办理" + cuccServiceOfferVo.getName());
                        }
                        else{
                            //提示，点击确定继续做
                            cuccServiceOfferVo.setIsEdit("2");
                            cuccServiceOfferVo.setRemark(KiteMapUtils.getString(menuCheckResult, "isOutOfCreditMsg"));
                        }
                    }
                }

                //用户跨域，不能办理停开机业务
                if(KiteStringUtils.equals(KeyConsts2.IS_CROSS_DOMAIN_T, KiteMapUtils.getString(menuCheckResult, "isCrossDomain"))
                  &&!KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())){
                    cuccServiceOfferVo.setIsEdit("0");
                    cuccServiceOfferVo.setRemark(KiteMapUtils.getString(menuCheckResult, "isCrossDomainMsg"));
                }

                //OA账号信息校验
                if(KiteStringUtils.equals(LocalKeyConsts.IS_OA_CHECK_F, KiteMapUtils.getString(menuCheckResult, "isOaInfoCheck"))
                   && KiteStringUtils.equalsAny(cuccServiceOfferVo.getServiceOfferId(),KiteMapUtils.getString(serviceOfferMap, "yywsl")
                    ,KiteMapUtils.getString(serviceOfferMap, "yscywsl"),KiteMapUtils.getString(serviceOfferMap, "hyyywsl"))
                    &&!KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())){
                    cuccServiceOfferVo.setIsEdit("0");
                    cuccServiceOfferVo.setRemark(KiteMapUtils.getString(menuCheckResult, "isOaInfoCheckMsg"));
                }

                if (!KiteStringUtils.equals(LocalKeyConsts.IS_OA_CHECK_F, KiteMapUtils.getString(menuCheckResult, "isOaInfoCheck"))) {
                    //沃云云账号不能操作：合营云业务受理
                    if (KiteStringUtils.equals(cateId, "2000998") && KiteStringUtils.equalsAny(cuccServiceOfferVo.getServiceOfferId(),KiteMapUtils.getString(serviceOfferMap, "hyyywsl"))
                        &&!KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())) {
                        cuccServiceOfferVo.setIsEdit("0");
                        cuccServiceOfferVo.setRemark("沃云云账号不能进行合营云业务受理");
                    }
                    //合营云后付费云账号不能操作：行业云业务受理、云市场业务受理
                    if (KiteStringUtils.equals(cateId, "2100982") && KiteStringUtils.equalsAny(cuccServiceOfferVo.getServiceOfferId(),KiteMapUtils.getString(serviceOfferMap, "yywsl")
                        ,KiteMapUtils.getString(serviceOfferMap, "yscywsl"))
                        &&!KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())) {
                        cuccServiceOfferVo.setIsEdit("0");
                        cuccServiceOfferVo.setRemark("合营云后付费云账号不能进行该操作");
                    }

                }

                // 体验包延期一次
                if(KiteStringUtils.equals(LocalKeyConsts.IS_CROSS_DOMAIN_T, KiteMapUtils.getString(menuCheckResult, "isDelayTime"))
                    && KiteStringUtils.equalsAny(cuccServiceOfferVo.getServiceOfferId(),KiteMapUtils.getString(serviceOfferMap, "tybyq"))
                    && !KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())){
                    cuccServiceOfferVo.setIsEdit("0");
                    cuccServiceOfferVo.setRemark(KiteMapUtils.getString(menuCheckResult, "isDelayTimeMsg"));
                }
                // 体验包延期时间
                if(KiteStringUtils.equals(LocalKeyConsts.IS_CROSS_DOMAIN_T, KiteMapUtils.getString(menuCheckResult, "isShutDownTime"))
                    && KiteStringUtils.equalsAny(cuccServiceOfferVo.getServiceOfferId(),KiteMapUtils.getString(serviceOfferMap, "tybyq"))
                    && !KiteStringUtils.equals("0", cuccServiceOfferVo.getIsEdit())){
                    cuccServiceOfferVo.setIsEdit("0");
                    cuccServiceOfferVo.setRemark(KiteMapUtils.getString(menuCheckResult, "isShutDownTimeMsg"));
                }
                if (KiteStringUtils.equals(serviceOfferMap.get("tybyq"), serviceOfferVO.getServiceOfferId())) {
                    //在途单
                    if (PassageOrderSwitch) {
                        if (passageOrderFlag) {
                            cuccServiceOfferVo.setIsEdit("0");
                            cuccServiceOfferVo.setRemark("用户存在在途单，不允许受理业务，请将在途单处理报竣");
                        }
                    }
                    else {
                        if (KiteStringUtils.equals(KeyConsts2.USER_STATE_HAS_ORDER, KiteMapUtils.getString(menuCheckResult, "hasOrder"))) {
                            cuccServiceOfferVo.setIsEdit("0");
                            cuccServiceOfferVo.setRemark(KiteMapUtils.getString(menuCheckResult, "hasOrderMsg"));
                        }
                    }
                }
                if (KiteStringUtils.equals(serviceOfferMap.get("yhyxh"),serviceOfferVO.getServiceOfferId())
                    && !KiteStringUtils.equals("0",cuccServiceOfferVo.getIsEdit())
                    && KiteStringUtils.equals(KeyConsts2.IS_WLW_PRODUCT_T,KiteMapUtils.getString(menuCheckResult, "preCancelAccount"))){
                    cuccServiceOfferVo.setIsEdit("2");
                    cuccServiceOfferVo.setRemark(KiteMapUtils.getString(menuCheckResult,"preCancelAccountMsg"));
                }

                cuccServiceOfferVoList.add(cuccServiceOfferVo);
            }
            cuccServiceOfferTypeVO.setServiceOfferViews(cuccServiceOfferVoList);
            cuccServiceOfferTypeVOList.add(cuccServiceOfferTypeVO);
        }

        // 以太网、SDH、互联网，跨域，不支持停开机（放到前面的提示校验）
        /*if(LocalAttrUtils.isCrossDomainForUserDetail(cateId, userDetailMap)) {
            cuccServiceOfferTypeVOList.forEach(serviceOfferType -> {
                List<CuccServiceOfferVo> serviceOfferVOList = serviceOfferType.getServiceOfferViews();
                if(serviceOfferVOList.size()>0){
                    serviceOfferVOList.removeIf(date -> KiteStringUtils.equalsAny(date.getServiceOfferId(), "2829","2830"));
                }
            });
        }*/
        return cuccServiceOfferTypeVOList;
    }

    @KiteTransactional
    @SuppressWarnings("deprecation")
    @ApiOperation(value = "收入归集场景初始化", notes = "收入归集场景初始化，返回场景实例标识")
    @PostMapping("/initCollectGroupScene")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "serviceOfferId", value = "服务动作", required = false),
        @ApiImplicitParam(name = "sceneActionType", value = "场景操作类型", required = false)
    })
    public DataResult<Map<String, Object>> initCollectGroupScene(@RequestParam(required = false) String serviceOfferId , @RequestParam(required = false) String sceneActionType) {
        String cartId = null;
        String offerId = DcSystemParamCache.getDcParamVal(LocalKeyConsts.COLLECTION_GROUP_OFFER_ID);
        serviceOfferId = Optional.ofNullable(serviceOfferId).orElse(ServiceOfferConsts.SERVICE_OFFER_ORDER);
        String custId = DcSystemParamCache.getDcParamVal(LocalKeyConsts.COLLECTION_GROUP_CUST_ID);
        //SpringUtil.getBean(LocalCustReceptionController.class).initContext(custId,"0");
        SpringUtil.getBean(LocalCustReceptionController.class).initTempCustContext(custId,"0");

        Offer offer = OfferCache.get(offerId);
        if (offer == null) {
            ErrorConsts.OFFER_NOT_FOUND.throwOut();
        }

        // 区分接口和前台
        CommonContext.setMoreAttrData(true);

        String sceneInstId = operateSceneService
            .createOfferSceneInst(serviceOfferId, offerId, KiteWebContext.getContext().getCustId(),
                KiteWebContext.getContext().getCust().getCustName(), ContextUtil.getUserId().toString(),
                ContextUtil.getLandId(), ContextUtil.getLoginInfo().getUserInfo().getPostRegionId().toString(), "-1",
                null).getResultObject();
        // 保存受理的SPU，记录最新受理商品
        this.operateSceneInstService.putExtParameter(sceneInstId, LocalKeyConsts.ACCEPT_GOODS_SPU, offerId);
        this.operateSceneInstService.putExtParameter(sceneInstId, KeyConsts.IS_NEED_ANSY_MORE_ATTR, KeyConsts.ZERO);

        if (!KiteStringUtils.isEmpty(sceneActionType)) {
            this.operateSceneInstService.putExtParameter(sceneInstId, "sceneActionType", sceneActionType);
        }
        this.sceneService.setSceneInstId(sceneInstId, cartId,
            KiteStringUtils.equals(ServiceOfferConsts.SERVICE_OFFER_ORDER, serviceOfferId) ?
                UnicodeOperTypeKite.OPERTYPE_1001 :
                serviceOfferId);
        Map<String, Object> result = new HashMap<>();
        result.put("offerId", offerId);
        result.put("offerType", Optional.ofNullable(offer.getOfferType()).orElse("11"));
        result.put("serviceOfferId", serviceOfferId);
        result.put("sceneInstId", sceneInstId);
        result.put("custId", custId);
        List<KiteOfferInst> offerInsts = Lists.newArrayList();
        offerInsts.addAll(this.querySceneInstService.listMainOfferInsts(sceneInstId));
        CuccPosServiceUtils.setExtParamValue(offerInsts.get(0), sceneInstId, "saleGoodsCode", offerId);
        CuccPosServiceUtils
            .setExtParamValue(offerInsts.get(0), sceneInstId, "saleGoodsName", OfferCache.get(offerId).getOfferName());
        this.operateSceneInstService.addInst(sceneInstId, offerInsts.get(0));
        return ErrorConsts.SUCCESS.getResult(result);
    }

    @KiteTransactional
    @ApiOperation(value = "商品变更场景初始化", notes = "商品变更场景初始化")
    @ApiImplicitParams({@ApiImplicitParam(name = "request", value = "商品变更场景初始化请求对象", required = true)
    })
    @PostMapping("/secondary/initGoodsModifyScene")
    public DataResult<InitSceneVO> initGoodsModifyScene(@RequestBody AbstractCreateGoodsModifySceneRequest request) {
        String newOfferId = request.getTargetOfferId();
        String cateId = request.getCateId();
        LoginInfo loginInfo = ContextUtil.getLoginInfo();
        IGoodsModifyService iGoodsModifyService = GoodsModifyServiceFactory.getInstance(GoodsModifyServiceEnum.codeOf(cateId));
        request.setStaffId(loginInfo.getUserInfo().getUserId().toString());
        request.setLanId(loginInfo.getUserInfo().getPostLanId());
        String sceneInstId = iGoodsModifyService.createGoodsModifyScene(request);
        KiteSceneInst sceneInst = querySceneInstService.getSceneInst(sceneInstId);
        sceneInst.setOperType("1008");
        // 保存受理的SPU，记录最新受理商品，为了触发规则
        this.operateSceneInstService.putExtParameter(sceneInstId, LocalKeyConsts.ACCEPT_GOODS_SPU, goodsService.getPromotionOfferId(newOfferId));
        PageNavigationVO pageNavigationVO = SpringUtil.getBean(SceneController.class)
            .getPageNavigation(request.getServiceOfferId(), OfferCache.get(newOfferId).getOfferType(), newOfferId,
                sceneInstId, null, null).getResultObject();
        if (pageNavigationVO == null) {
            ErrorConsts.BUSI_COMMON_ERROR.throwOut("未配置模板或页面流程,请联系管理员");
        }
        return ErrorConsts.SUCCESS.getResult(new InitSceneVO(newOfferId, sceneInstId, pageNavigationVO, cateId, KiteWebContext.getContext().getCustId()));
    }

    // 调用接口获取订单中心的重新配置页面流程  只针对双线业务
    private void OrderProcessFlowchart(String orderId, PageNavigationVO pageNavigationVO) {
        List<KitePageDefine> pageDefineList = new ArrayList<KitePageDefine>();
        ProcessFlowchartVO flowchartVO = flowService.getOrderProcessFlowchart(orderId, "5");
        List<ProcessFlowchartDTO> flowchartList = flowchartVO.getFlowchartList();
        if (Objects.nonNull(flowchartList) && flowchartList.size() > 0) {
            for (ProcessFlowchartDTO processFlowchartDTO : flowchartList) {
                KitePageDefine pageDefine = new KitePageDefine();
                pageDefine.setStatusCd(LocalKeyConsts.COMMON_STATUS_VALIDATE);
                pageDefine.setDefineId(String.valueOf(processFlowchartDTO.getSequ()));
                pageDefine.setName(processFlowchartDTO.getName());
                if(KiteStringUtils.equals(processFlowchartDTO.getStatus(),"EXECUTING")) {
                    pageNavigationVO.getPageDefineList().forEach(pageInfo -> {
                        if(Objects.nonNull(pageInfo)&& KiteStringUtils.isNotEmpty(pageInfo.getPageUrl())){
                            pageDefine.setPageUrl(pageInfo.getPageUrl());
                        }
                    });
                }
                pageDefineList.add(pageDefine);
            }
            pageNavigationVO.setPageDefineList(pageDefineList);
        }
    }

    private DataResult<InitSceneVO> getSecSceneNavigation(String serviceOfferId, Map dataMap, String operType) {
        KitePosDTO kitePosDTO = (KitePosDTO) KiteMapUtils.getObject(dataMap, "kitePosDTO");
        String tacheCode;
        String objId = null;
        String cateId = null;
        List<KitePosGoodsDTO> offerInsts = kitePosDTO.getGoods();
        for (KitePosGoodsDTO offerInst : offerInsts) {
            String offerId = offerInst.getCode();
            if (GoodsHelper.isGift(offerId)) {
                objId = offerId;
                cateId = offerInst.getCatagoryId();
                break;
            }
            if (GoodsHelper.isGroupGood(offerInst.getCatagoryId(),offerId)) {
                objId = offerId;
                cateId = offerInst.getCatagoryId();
                break;
            }
            if (!GoodsInfoTransfer.isAddRoleOffer(offerId, offerInst.getCatagoryId())) {
                objId = offerId;
                cateId = offerInst.getCatagoryId();
            }
        }
        PageNavigationReqDTO reqDTO = new PageNavigationReqDTO();
        reqDTO.setServiceOfferId(serviceOfferId);
        if (LocalServiceOfferConsts.SERVICE_OFFER_RESOURCE_CHECK.equals(operType)
            && LocalServiceOfferConsts.SERVICE_OFFER_FOLLOW.equals(serviceOfferId)) {
            tacheCode = "OrderArchive";
        }
        else if (LocalServiceOfferConsts.SERVICE_OFFER_FOLLOW.equals(serviceOfferId)
        && !KiteStringUtils.equalsAny(cateId, "2004014", "2004015")) {
            // 追单重新计算serviceOfferId，兼容云联网存量数据
            String newServiceOfferId = KiteMapUtils.getString(dataMap, "serviceOfferId");
            if (KiteStringUtils.equals(newServiceOfferId, "1001")) {
                newServiceOfferId = "1";
            }
            String upServiceOfferId = KiteMapUtils.getString(dataMap, "upServiceOfferId");
            if (KiteStringUtils.isNotEmpty(upServiceOfferId)) {
                reqDTO.setServiceOfferId(upServiceOfferId);
            }
            else {
                // 非产品变更的二次类业务追单,支持用自身的服务提供配置模板
                reqDTO.setServiceOfferId(newServiceOfferId);
            }
            tacheCode = "OrderChase";
        }
        else {
            tacheCode = "OrderChange";
        }
        reqDTO.setTacheCode(tacheCode);
        reqDTO.setObjId(objId);
        reqDTO.setCateId(cateId);
        DataResult<PageNavigationVO> pageNavigationVO = SpringUtil.getBean(PageNavigationService.class)
            .getPageNavigationVO(reqDTO);
        Map result = new HashMap();
        PageNavigationVO resultObject = Objects.nonNull(pageNavigationVO) ? pageNavigationVO.getResultObject() : null;
        InitSceneVO initSceneVO = new InitSceneVO(objId, "", resultObject, result, cateId, KiteWebContext.getContext().getCustId());
        return ErrorConsts.SUCCESS.getResult(initSceneVO);
    }
}
